Дождаться окончания одного из нескольких потоков? - PullRequest
1 голос
/ 24 ноября 2010

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

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

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

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

Ответы [ 3 ]

3 голосов
/ 24 ноября 2010

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

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

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 голос
/ 24 ноября 2010

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...