У меня три потока, один из которых является основным, а два других являются рабочими.Первый поток, когда есть работа, которую нужно выполнить, пробуждает один из двух потоков.Каждый поток при пробуждении выполняет некоторые вычисления и, выполняя это, если находит больше работы, может разбудить другой рабочий поток или просто решить выполнить работу самостоятельно (например, добавив работу в локальную очередь).В то время как рабочие потоки имеют работу, основной поток должен ждать, пока работа не будет выполнена.Я реализовал это с помощью условных переменных следующим образом (код, представленный здесь, скрывает много деталей, пожалуйста, спросите, есть ли что-то непонятное):
MAIN THREAD (псевдокод):
//this function can be called from the main several time. It blocks the main thread till the work is done.
void new_work(){
//signaling to worker threads if work is available
//Now, the threads have been awakened, it's time to sleep till they have finished.
pthread_mutex_lock(&main_lock);
while (work > 0) //work is a shared atomic integer, incremented each time there's work to do and decremented when finished executing some work unit
pthread_cond_wait(&main_cond);
pthread_mutex_unlock(&main_lock);
}
РАБОЧИЕ РЕЗЬБЫ:
while (1){
pthread_mutex_lock(&main_lock);
if (work == 0)
pthread_cond_signal(&main_cond);
pthread_mutex_unlock(&main_lock);
//code to let the worker thread wait again -- PROBLEM!
while (I have work to do, in my queue){
do_work()
}
}
Вот проблема: когда рабочий поток пробуждает основной поток, я не уверен, что рабочий поток вызывает ожидание, чтобы перевести себя в состояние ожидания новой работы.Даже если я реализую это ожидание с другой условной переменной, может случиться так, что основной поток не активен, выполняет некоторую работу, пока не достигнет точки, в которой он должен пробудить поток, который еще не вызвал ожидание ... и это можетпривести к плохим результатам.Я пробовал несколько способов решить эту проблему, но я не мог найти решение, может быть, есть очевидный способ решить его, но я его упускаю.
Можете ли вы предоставить схему для решения этой проблемыпроблемы?Я использую язык C и могу использовать любой механизм синхронизации, который вы считаете подходящим, например pthreads или posix семафоры.
Спасибо