Я работаю над программой, использующей mpi (openmpi 1.4.3) и pthreads, работающей в c ++ под linux.
некоторые узлы mpi имеют систему массового обслуживания, реализованную с помощью pthreads.
Идея - это простой поток, добавляющий элементы в очередь, и несколько других «работающих» потоков, выбирающих объекты и выполняющих над ними свою работу (не ракетостроение).
Пожалуйста, рассмотрите 2 примера моих рабочих тем, которые собирают элементы.
Первый пример работает нормально, если не указана оптимизация -O3. В этом случае он начинает бесконечно зацикливаться, ничего не поднимая.
while (true){
if (t_exitSignal[tID]){
dorun = false;
break;
}
//cout<<"w8\n";
//check if queue has some work for us
if (!frame_queue->empty()){
//try to get lock and recheck that queue no empty
pthread_mutex_lock( &mutex_frame_queue );
if (!frame_queue->empty()){
cout<<"Pickup "<<tID<<endl;
con = frame_queue->front();
frame_queue->pop();
t_idling[tID] = false;
pthread_mutex_unlock( &mutex_frame_queue );
break;
}
pthread_mutex_unlock( &mutex_frame_queue );
}
}
Теперь рассмотрим этот, точно такой же код, за исключением того, что мьютекс gettimg заблокирован, прежде чем я проверю очередь-> empthy. Эта работа отлично работает для всех уровней оптимизации.
while (true){
if (t_exitSignal[tID]){
dorun = false;
break;
}
//cout<<"w8\n";
//try to get lock and recheck that queue no empty
pthread_mutex_lock( &mutex_frame_queue );
//check if queue has some work for us
if (!frame_queue->empty()){
cout<<"Pickup "<<tID<<endl;
con = frame_queue->front();
frame_queue->pop();
t_idling[tID] = false;
pthread_mutex_unlock( &mutex_frame_queue );
break;
}
pthread_mutex_unlock( &mutex_frame_queue );
}
На всякий случай, если что-то изменится, так я заполняю очередь из другого потока
pthread_mutex_lock( &mutex_frame_queue );
//adding the same contianer into queue to make it available for threads
frame_queue->push(*cursor);
pthread_mutex_unlock( &mutex_frame_queue );
У меня вопрос: почему перестает работать первый пример кода, почему я компилирую с опцией -O3?
Любое другое предложение для системы массового обслуживания?
Большое спасибо!
РЕШЕНИЕ: Это то, что я придумал в конце. Кажется, работает намного лучше, чем любой из методов выше. (на всякий случай, если кому-то интересно;)
while (true){
if (t_exitSignal[tID]){
dorun = false;
break;
}
//try to get lock and check that queue no empty
pthread_mutex_lock( &mutex_frame_queue );
if (!frame_queue->empty()){
con = frame_queue->front();
frame_queue->pop();
t_idling[tID] = false;
pthread_mutex_unlock( &mutex_frame_queue );
break;
}else{
pthread_cond_wait(&conf_frame_queue, &mutex_frame_queue);
pthread_mutex_unlock( &mutex_frame_queue );
}
}
Добавление
pthread_mutex_lock( &mutex_frame_queue );
//adding the same contianer into queue to make it available for threads
frame_queue->push(*cursor);
//wake up any waiting threads
pthread_cond_signal(&conf_frame_queue);
pthread_mutex_unlock( &mutex_frame_queue )