2010-11-24 8 views
1

Я реализую пул потоков. Работа, требуемая каждым потоком, составляет 1-10 секунд CPU, поэтому я рад, что у меня есть традиционный пул потоков с рабочими, или я счастлив создать новый поток для каждой единицы работы. Это не имеет значения.Подождите, пока закончится один из нескольких потоков?

Я хотел бы иметь некоторый путь к потоку основного управления, чтобы знать, когда один из N рабочих потоков заканчивает свою работу и готов к большему (или его времени для запуска другого). Я посмотрел на pthread_join и pthread_cond_wait. Кажется, что нет способа подождать одного из N. Поэтому я подумал о том, что главный поток имеет переменную, которую он использует, чтобы заснуть и заставить рабочих разбудить ее. Это, похоже, работает, если рабочие не умрут. Однако, если они умирают, между временем, когда рабочий просыпает контроллер и время, когда он умирает, есть окно, с которым я не хочу иметь дело.

Я смотрел TBB Intel, но он выглядит намного сложнее, чем мне нужно.

Есть ли простой эквивалент в PTHREADS для WaitForMultipleObjects в Microsoft Windows?

+1

Я отметил это как C, пожалуйста, не стесняйтесь изменять его, если это не так. – 2010-11-24 07:45:19

+1

Вы пробовали цикл (N) для pthread_join. http://opengroup.org/onlinepubs/007908799/xsh/pthread_join.html – 2010-11-24 07:45:44

+0

Я согласен с small_ticket. Почему не работает цикл для n pthread_joins? – Jay 2010-11-24 08:01:14

ответ

3

Это условно простой пример использования переменных условия.

Имейте целое число количества активных рабочих элементов, защищенных мьютексом. Кроме того, есть две переменные условия: одна для сигнализации рабочих потоков, которые работают в очереди, а другая - для основного потока, который завершен потоком. Что-то вроде:

main: 
    set freethreads to numthreads 
    init mutex M, condvars TOMAIN and TOWORKER 
    start N worker threads 
    while true: 
     wait for work item 
     claim M 
     while freethreads == 0: 
      cond-wait TOMAIN, M 
     put work item in queue 
     decrement freethreads 
     cond-signal TOWORKER 
     release M 

worker: 
    init 
    while true: 
     claim M 
     while no work in queue: 
      cond-wait TOWORKER, M 
     get work to local storage 
     release M 
     do work 
     claim M 
     increment freethreads 
     cond-signal TOMAIN 
     release M 

Обратите внимание, что петли выполняются вечно. В действительности, были бы сигналы, которые заставили бы их выйти и запустить код завершения/очистки.

1

Вы думаете об использовании счетного семафора?

1

С точки зрения архитектуры, это будет ответственность пула потоков. Синхронизация между рабочими и пулом должна существовать.

pthread_mutex_lock() или счетный семафор (sem_wait() и sem_post()) хорош для такой синхронизации. Один из способов сделать это можно проиллюстрировать следующим образом:

  1. пул init является семафором подсчета, вызывая: sem_init (p_to_sem_t, 0, int n);
  2. n работники приобретают семафор путем вызова: sem_wait();
  3. бассейн ждет, пока рабочие вернутся, позвонив: sem_wait();
  4. пул проверяет счет семафора, чтобы убедиться, что все рабочие припаркованы.
  5. работник (ы) освобождает свою блокировку, когда они выходят, вызывая: sem_post();
Смежные вопросы