сигнал о том, что пакет потоков завершен до мастер-потока - PullRequest
1 голос
/ 30 мая 2011

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

При запуске программы я выделяю статический пул рабочих и главный поток, которые живут на протяжении всего выполнения программы. (псевдокод ниже)

void *worker(){
   while(1){
   //perworker mutex lock
   //wait for workerSIGNAL
   //do calculations
   //perworker mutex unlock
   }
}

Мой главный поток сигнализирует всем моим рабочим, когда рабочие закончили, они ждут следующего сигнала от главного потока. (псевдокод ниже)

void *master(){
  while(1){
    //masterMutex lock
    //wait for masterSignal
    //signal all workerthread to start running
    /*
      SHOULD WAIT FOR ALL WORKER THREADS TO FINISH 
      (that is when workers are done with the calculations,
      and are waiting for a new signal) 
     */
    //materMutex unlock
  }
}

Мой главный поток получает сигнал от другой части моего кода (не потока), что означает, что существует только один главный поток. (псевдокод ниже)

double callMaster(){
  //SIGNAL masterThread
  //return value that is the result of the master thread
}

Моя проблема в том, как заставить masterthread ожидать выполнения всех рабочих (ожидание следующего workerSignal)?

Мое решение необычайно сложное. У меня есть барьер в моих рабочих потоках, который ожидает завершения всех рабочих потоков, а затем из одного из моих потоков (threadId = 0) я сигнализирую условное условие workerDone, ожидаемое в нижней части моей главной темы.

Работает, но не красиво, любые идеи по улучшению приветствуются.

Спасибо.

Ответы [ 3 ]

3 голосов
/ 30 мая 2011

Рассматривали ли вы использование pthread_join http://kernel.org/doc/man-pages/online/pages/man3/pthread_join.3.html? Похоже, вы используете сигнал для связи между потоками.Хотя это может быть уместно в некоторых ситуациях, я думаю, что в вашем случае использование pthread_join может упростить ваш код.

Ниже приведен пример псевдокода:

//this goes in your main thread
for (int i = 0; i < num_threads; ++i)
    pthread_join(thread_id[i], ...

Таким образом, ваш основной поток будет блокироваться до тех пор, пока не завершатся все потоки, ваши рабочие потоки в массиве thread_id.

2 голосов
/ 30 мая 2011

Вы хотите использовать барьер.Барьеры инициализируются счетом N, и когда какой-либо поток вызывает pthread_barrier_wait, он блокируется до тех пор, пока в общей сложности N потоков не достигнет pthread_barrier_wait, а затем все они возвращаются, и барьер можно использовать снова (стот же счет).

Подробности см. в документации по POSIX:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_barrier_wait.html

0 голосов
/ 30 мая 2011

В Java вы можете использовать здесь циклический барьер с начальным значением, равным количеству рабочих потоков.

Ссылка на этот барьер передается каждому рабочему потоку, который в конце одногоДля выполнения своей работы вызовите барьер.await ().

Основная программа будет ожидать () на барьере до тех пор, пока все рабочие потоки не достигнут точки своего выполнения и не будет вызывать барьер. АВТА ().

Только когда все рабочие потоки вызвали барьер.await (), барьер будет поднят, а главный может продолжаться.

Циклические барьеры аналогичны защелкам, за исключением того, что барьер является циклическим, что позволяет его сброситьна неопределенный срок.Так что в случае основного нахождения в цикле лучшим вариантом является циклический барьер.

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