Асинхронное и многопоточное программирование в MQL - страница 34

 
Andrei Novichkov:
Но вот мне другое интересно, есть ли такие задачи, которые действительно требовали бы пула потоков? Не просто - создал поток - забыл и ждем, когда закончится, а именно пула, по типу того, как это у Уильямса описано? Там приведен пример, кажется банкомата, если я не путаю, а у нас какой задачей может быть оправдано такое чудо юдо. Я пока такой задачи не могу придумать. И почему тогда уж действительно не посмотреть на ThreadPool, где уже все сделано, документация есть, примеры есть.

Если честно, то пока сам не уловил особого смысла между std::async и пулом потоков, за исключением того, что  std::async автоматически создаёт и удаляет поток для выполняемой задачи.
А для использования пула потока, нужно заранее знать количество используемых потоков в программе, и устанавливать это количество для пула явно.
Получается что пул потоков, статический по количеству потоков, хотя возможно это не так, не могу утверждать.
Но в книге Уильямс пишет, что пул потоков рекомендуется использовать когда есть очень много задач для выполнения в std::thread.
И возможно это не относится к std::async, пока не уловил до конца смысл.
А асинхронность очень востребована в сетевых решениях, и мульти символьных стратегиях, да и для нагруженных расчётов тоже полезно.
Но имея в стандарте std::async и std::promise, мне кажется в создании пула потоков нет необходимости.

 

Ещё возник вопрос по настройке проекта для dll.
Как избавиться от не используемых функций, которое автоматом тянуться компиляторами в dll зависимость?

Перепробовал уже разные среды разработок, и каждая из них тянет свою неиспользуемую функцию.
MSVS_2017 вообще тянет свои рантайм зависимости, от которых наверно не избавиться.
По этому перепробовал разные IDE, но они тоже тянут не используемые функции.
Как от них избавиться?

 
Roman:

Если честно, то пока сам не уловил особого смысла между std::async и пулом потоков, за исключением того, что  std::async автоматически создаёт и удаляет поток для выполняемой задачи.
А для использования пула потока, нужно заранее знать количество используемых потоков в программе, и устанавливать это количество для пула явно.
Получается что пул потоков, статический по количеству потоков, хотя возможно это не так, не могу утверждать.
Но в книге Уильямс пишет, что пул потоков рекомендуется использовать когда есть очень много задач для выполнения в std::thread.
И возможно это не относится к std::async, пока не уловил до конца смысл.
А асинхронность очень востребована в сетевых решениях, и мульти символьных стратегиях, да и для нагруженных расчётов тоже полезно.
Но имея в стандарте std::async и std::promise, мне кажется в создании пула потоков нет необходимости.

Так основной смысл async - это юзать пул потоков, избавиться от накладных расходов связанных с постоянным созданием/удалением потоков, если async это не делает, то грош ему цена.

Ну вообще, я об async слишком плоход думал, видимо. Простой тест показывает его как вполне адекватную вещь:

#include <future>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    cout << "Main thread id: " << this_thread::get_id() << endl;
    for (int i = 0;  i < 2;  ++ i){
       cout << "------------------------" << endl;
       vector<future<void>> futures;
       for (int i = 0; i < 10; ++i)
       {
          this_thread::sleep_for(1ms);
          auto fut = async([]{
                              this_thread::sleep_for(1s);
                              cout << this_thread::get_id() << '\n';
                           });
          futures.push_back(move(fut));
       }
       for (auto &f : futures)
          f.wait();
    }

    cout << endl;
}

Main thread id: 140657228855104

140657228850944
140657220458240
140657212065536
140657203672832
140657195280128
140657186887424
140657178494720
140657170102016
140657161709312
140657153316608
------------------------
140657153316608
140657161709312
140657170102016
140657178494720
140657228850944
140657220458240
140657212065536
140657203672832
140657195280128
140657186887424

Видно, что для второй пачки заданий async использовал раннее созданные потоки, не стал создавать новых. Так что я не совсем заслужено его поливал, наверное.

 
Roman:

Ещё возник вопрос по настройке проекта для dll.
Как избавиться от не используемых функций, которое автоматом тянуться компиляторами в dll зависимость?

Для mingw должна помочь опция -static со статик он перестает генерить pic

 

Более жёсткий тест async

#include <future>
#include <iostream>
#include <vector>
#include <mutex>
#include <set>
using namespace std;

mutex mtx;
set<thread::id> id;
atomic<unsigned> atm{0};

int main()
{
   for (int i = 0;  i < 10000;  ++ i) {
      vector<future<void>> futures;
      for (int i = 0; i < 10; ++i) {
         auto fut = async(launch::async,[]{
                                           ++ atm;
                                           lock_guard<mutex> lck{mtx};
                                           id.insert( this_thread::get_id() );
                                        });
         futures.push_back(move(fut));
      }
   }

   cout << "executed " << atm << " tasks, by " << id.size() << " threads\n";
}
// cout: executed 100000 tasks, by 10 threads

Ну в общем да, нормально работает. Почему я о нём так плохо думал? Наверное кривые реализации на заре с++11 ...

ЗЫ: но надо отметить, что шибко тормозная async() c политикой lanch::async, если заменить на lanch::deferred (+ подождать завершиня заданий в конце первого цикла), то этот простой тест начинает работать в 30 раз быстрее !!! Вот и многопоточность )). Поэтому остаётся место для самодельного пула потоков, мне кажется, что можно сделать много быстрее стандартного.

 
Roman:

Ещё возник вопрос по настройке проекта для dll.
Как избавиться от не используемых функций, которое автоматом тянуться компиляторами в dll зависимость?

Перепробовал уже разные среды разработок, и каждая из них тянет свою неиспользуемую функцию.
MSVS_2017 вообще тянет свои рантайм зависимости, от которых наверно не избавиться.

Принять это как должное и забыть, или забить.
Чем и чему это мешает? Оставьте глупости соседям.)
Языки высокого уровня созданы, чтобы программиста не заботили детали. Не царское это дело. Да, и откуда вам знать, что нужно, что не нужно. Компилятору видней.
 
Vict:

Более жёсткий тест async

Ну в общем да, нормально работает. Почему я о нём так плохо думал? Наверное кривые реализации на заре с++11 ...

ЗЫ: но надо отметить, что шибко тормозная async() c политикой lanch::async, если заменить на lanch::deferred (+ подождать завершиня заданий в конце первого цикла), то этот простой тест начинает работать в 30 раз быстрее !!! Вот и многопоточность )). Поэтому остаётся место для самодельного пула потоков, мне кажется, что можно сделать много быстрее стандартного.

Я не дочитал до конца и решил предложить Вам выполнить запуск с флагом deferred ))))) Логично, если такой тест выполняется быстрее, мне вообще представляется такой способ использования предпочтительнее, зачем ставить жесткие рамки. Хотел сказать спасибо за Вашу ссылку на Гит, с интересом посмотрел )) Очень понравилось, что там два варианта - с бустом и без.

Roman:

Ещё возник вопрос по настройке проекта для dll.
Как избавиться от не используемых функций, которое автоматом тянуться компиляторами в dll зависимость?

Перепробовал уже разные среды разработок, и каждая из них тянет свою неиспользуемую функцию.
MSVS_2017 вообще тянет свои рантайм зависимости, от которых наверно не избавиться.
По этому перепробовал разные IDE, но они тоже тянут не используемые функции.
Как от них избавиться?

А как без рантайма? И да, он везде разный. Не, без рантайма ни ткнуть, ни дернуть )))) Это вы еще с QT не работали, вот где целая гирлянда сосисок из ДЛЛ тянется.


 
Andrei Novichkov:

Я не дочитал до конца и решил предложить Вам выполнить запуск с флагом deferred ))))



Зачем нужен async() с флагом deferred? Я действительно не понимаю, не объясните?

 
Vict:

Зачем нужен async() с флагом deferred? Я действительно не понимаю, не объясните?

А собственно почему бы про флаг не прочитать в документации? На https://en.cppreference.com . И примеры с обсуждением  на stackoverflow.com. Я обычно эти источники информации использую, что и Вам советую.

 
Andrei Novichkov:

А собственно почему бы про флаг не прочитать в документации? На https://en.cppreference.com . И примеры с обсуждением  на stackoverflow.com. Я обычно эти источники информации использую, что и Вам советую.

MSDN. Полная документация. Остальное только доп. материал.
Причина обращения: