эффективная реализация thread pool
От: barney  
Дата: 17.05.18 05:51
Оценка:
Привет желающим присоединиться к исследованию 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(); заблокируется до появления новых данных в очереди

std::function<void(void)> Queue::pop() {
cond.wait();
...
}

void Queue::push(std::function<void(void) f) {
...
cond.signal();
}


Т.е каждый поток может сделать push() и каждый же поток — заблокироваться и заснуть на pop() до поступления работы.

Вопросы, которые не очень ясны.

1) Какой механизм меж-потоковой синхронизации?
Например я хочу гарантировать очередь исполнения моих ворков

допустим, из разных потоков я диспатчу:
dispatch(work1) | dispatch(work2)

я хочу чтобы work1 гарантированно исполнилась перед work2
при этом, чтобы потоки не простаивали
для этого work1 нужно не просто разместить в очереди до work2
а и гарантировать что поток, исполняющий work1 закончится до того, как другой поток возьмется за work2
Возможно тут нужны некие барьеры

2) Как эффективно передается Work между потоками?
Я так понимаю, что все thread используют общую память т.е. нет никакой нужды ничего никуда копировать? Или как?
Будет ли эффективной передача std::function по значению?

3) Как вообще делаются барьеры?
т.е чтобы был некий dispatch_barrier() который заставит все задиспатченные ранее Work выполниться до него гарантированно,
при этом сохранив возможность после него делать новые dispatch() просто добавляя новые Work в очередь
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.