我用等待條件和互斥從Linux上的並行線程做處理之間的同步一個奇怪的問題。請注意,這不僅僅是一個進程中的線程之間。線程在多進程設置等待等待條件沒有被驚醒
我的使用情況是有創建資源(在我的圖片),並將它們保存到共享內存區,更新關於資源的一些信息,然後信號等待消費者的生產者。共享內存和元數據部分工作正常,所以我會離開它,問題是信號無法可靠地工作。用例很簡單,因爲消費者如果丟失一個或兩個圖像並不重要,如果消費者還沒有時間讀取它,生產者基本上只覆蓋一箇舊圖像。所以等待條件只需要處理喚醒消費者,我不需要有任何資源計數或其他數據。
兼顧生產者和消費者有這樣的結構:
struct EventData {
pthread_mutex_t mutexHandle;
pthread_cond_t conditionHandle;
};
在消費過程中的線程坐着等待事情發生:
pthread_mutex_lock(&eventData->mutexHandle);
pthread_cond_wait(&eventData->conditionHandle, &eventData->mutexHandle);
thread_mutex_unlock(&eventData->mutexHandle);
生產過程做到這一點時,它創建了一個圖像,將其保存到共享內存中,並準備讓消費者抓取圖像:
pthread_mutex_lock(&eventData->mutexHandle);
pthread_cond_signal(&eventData->conditionHandle);
// also tried:
//pthread_cond_broadcast(&eventData->conditionHandle);
pthread_mutex_unlock(&eventData->mutexHandle);
這對我來說看起來相當不錯,它在某種程度上起作用。製片人可以在沒有任何問題的情況下向消費者發出大約100-1000次的信號,消費者醒來,抓住圖像並顯示它,結果是我可以看到移動的視頻。在某些時候,通常大約幾百幀,消費者將在pthread_cond_wait()中凍結,並且永遠不會返回。製作人仍然樂意創建圖像,調用pthread_cond_signal()並繼續沒有問題。消費者並沒有完全凍結,只有執行pthread_cond_wait()的線程,其他應用程序運行沒有問題。
那麼,什麼原因,當它從一個線程移動到另一個線程在另一個進程中迷路的信號。消費者凍結前通常需要5-20秒,醒來的次數也會在100到1000之間變化(根據迄今爲止的數值)。
互斥體,等待條件不平凡的默認進程間共享,我用這個設置創建原語:
EventData * eventData;
int fd = open(tmpnam(NULL), O_RDWR | O_CREAT | O_EXCL, 0666);
if (fd < 0) {
// failed to open file for event
}
if (ftruncate(fd, sizeof (eventData)) < 0) {
// failed to truncate file
}
// setup attributes to allow sharing between processes
pthread_condattr_init(&conditionAttribute);
pthread_condattr_setpshared(&conditionAttribute, PTHREAD_PROCESS_SHARED);
pthread_mutexattr_init(&mutexAttribute);
pthread_mutexattr_setpshared(&mutexAttribute, PTHREAD_PROCESS_SHARED);
// map memory for the event struct
eventData = (EventData *) mmap(NULL, sizeof(EventData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close (fd);
// finally initialize the memory
pthread_mutex_init(&eventData->mutexHandle, &mutexAttribute);
pthread_cond_init(&eventData->conditionHandle, &conditionAttribute);
以上是由創建互斥黨完成和等待條件。該文件,即使用tmpnam(NULL)的名稱是在保存和傳遞給其他進程打開的現實:
int fd = open(nameOfEventFile, O_RDWR, 0666);
if (fd < 0) {
// failed to open file for event
}
eventData = (EventData *) mmap(NULL, sizeof(EventData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
我在這裏沒有看到錯誤,並希望一些線索,以什麼可能出問題,尤其是它隨機運行一些時間。
請注意,一般來說,您希望在'while(!some_condition)pthread_cond_wait(...);'等循環中使用'pthread_cond_wait'。這應該防止您等待可能已經發生的事件。 – Hasturkun