Привет желающим присоединиться к исследованию Thread Pool
Насколько я понимаю, Thread Pool это вариация на тему multiple producers/multiple consumers.
Схематически, должно быть так:
0. Нужна конкурентная queue очередь
1. Делается N worker threads — например, N = количеству аппаратных параллельных ядер
2. В каждом worker запускается "выгребатель" работы из очереди
3. Функция dispatch принимает кусочки работы (например std::function) и ложит их в очередь
С точки зрения поставщика "кусочков работы" АПИ будет выглядеть например так:
void doer() {
Work work1 = [](){} /// Work обертка может быть std::function
Pool::dispatch(work1);
}
Эффективно реализовать очередь можно с помощью condition variable
Т.е auto work = queue.pop(); заблокируется до появления новых данных в очереди
Т.е каждый поток может сделать push() и каждый же поток — заблокироваться и заснуть на pop() до поступления работы.
Вопросы, которые не очень ясны.
1) Какой механизм меж-потоковой синхронизации?
Например я хочу гарантировать очередь исполнения моих ворков
допустим, из разных потоков я диспатчу:
dispatch(work1) | dispatch(work2)
я хочу чтобы work1 гарантированно исполнилась перед work2
при этом, чтобы потоки не простаивали
для этого work1 нужно не просто разместить в очереди до work2
а и гарантировать что поток, исполняющий work1 закончится до того, как другой поток возьмется за work2
Возможно тут нужны некие барьеры
2) Как эффективно передается Work между потоками?
Я так понимаю, что все thread используют общую память т.е. нет никакой нужды ничего никуда копировать? Или как?
Будет ли эффективной передача std::function по значению?
3) Как вообще делаются барьеры?
т.е чтобы был некий dispatch_barrier() который заставит все задиспатченные ранее Work выполниться до него гарантированно,
при этом сохранив возможность после него делать новые dispatch() просто добавляя новые Work в очередь