В настоящее время я работаю с переменными условий для синхронизации двух потоков (pthreads), и я получаю неожиданное поведение, когда, хотя я проверял, что поток уже ожидает состояния, он делает не будите, когда другая нить сигнализирует о состоянии.Состояние ожидания pthread не всегда срабатывает по сигналу
Возможно, стоит отметить, что я запускал это в среде рабочего стола, и он работает, как ожидалось, но эта проблема возникает, когда я запускал программу во встроенной среде с помощью uclibc.
Чтобы устранить эту проблему, урезанная мой код, чтобы только два потока, выполняющих блокировки/разблокировки/сигнализации, которая приведена ниже:
#include <stdio.h>
#include <pthread.h>
#include <stdbool.h>
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition1 = PTHREAD_COND_INITIALIZER;
pthread_cond_t condition2 = PTHREAD_COND_INITIALIZER;
bool predicate1 = false;
bool predicate2 = false;
static void * ThreadFunc2(void * arg) {
sleep(1); // For testing purposes, ensures this thread is run after Thread1
pthread_mutex_lock(&mutex2);
while(1) {
pthread_mutex_lock(&mutex1);
// Do some work - Eg receive some data from a socket
predicate1 = false;
pthread_cond_signal(&condition1);
pthread_mutex_unlock(&mutex1);
predicate2 = true;
while(predicate2 == true)
pthread_cond_wait(&condition2, &mutex2);
// Do some more work - Eg send response data to socket
}
}
static void * ThreadFunc1(void * arg) {
int result;
pthread_mutex_lock(&mutex1);
while(1) {
predicate1 = true;
while(predicate1 == true)
pthread_cond_wait(&condition1, &mutex1);
// Do some work - Eg process data on the socket and prepare response data to be sent
pthread_mutex_lock(&mutex2);
predicate2 = false;
pthread_cond_signal(&condition2);
pthread_mutex_unlock(&mutex2);
}
}
int main(int argc, char * argv[]) {
pthread_t thread1Id, thread2Id;
pthread_create(&thread1Id, NULL, ThreadFunc1, NULL);
pthread_create(&thread2Id, NULL, ThreadFunc2, NULL);
while(1) {
sleep(1);
}
return 0;
}
Если исключить все заявления, относящиеся к mutex2/condition2/predicate2, то два потока работают вместе, как ожидалось.
С кодом, указанным выше, через короткий промежуток времени (поскольку вся работа была удалена, каждый цикл выполняется очень быстро), условие wait1 в ThreadFunc1 не проснется, даже если оно сигнализируется Threadfunc2, приводящим к приложению остановить.
Также, чтобы помочь мне отлаживать, я переопределил функции pthread_ *, чтобы напечатать сообщение для stdout с соответствующими номерами строк до вызова фактических функций pthread_ *. Это позволило мне следить за потоком каждой операции pthread и убедиться, что сигнал отправляется в состояние ожидания.
Может ли кто-нибудь помочь мне пролить свет на любые потенциальные проблемы, которые могут присутствовать в моей реализации выше?
Заранее благодарим за любые предложения.
Ваш примерный код никогда не устанавливает 'predicate2' в' false'. – caf
Я добавил отсутствующую инструкцию predicate2, как отметил @caf - Спасибо. К сожалению, этот вопрос все еще остается. – wei
Можете ли вы опубликовать полную тестовую программу (похоже, ее не должно быть намного больше), команда, используемая для создания программы и информации о используемой версии платформы и инструментов? Я не могу воспроизвести с достаточным количеством лесов, добавленных для запуска потоков и нескольких вызовов 'puts()', чтобы убедиться, что прогресс уже сделан. Это на x86 Linux 3.0 с gcc 4.6.1. –