我正在撰寫一個程式,它從websocket接收資料,并在執行緒池中處理這些資料。 當處理器有2個或更多核心時,我遇到了pthread_cond_wait的問題。在pthread_cond_signal信號發出后,所有運行在不同核心上的執行緒都會收到。例如,如果我有兩個核心,那么信號將同時到達位于這兩個核心的兩個執行緒。 如果我有單核處理器,一切都很好。 為了讓程式在多核處理器上正常作業,我必須做什么?這樣,只有一個執行緒收到信號開始作業。 我寫了一個我的代碼的例子,用生成的隨機文本資料而不是websocket資料。
#include<stdio.h>/span>
#include<stdlib.h>/span>
#include<cstring>
#include<pthread.h>/span>
#include<unistd.h>
pthread_attr_t attrd;
pthread_mutex_t mutexQueue。
pthread_cond_t condQueue;
char textArr[128][24]; //array with random text to work.
int tc; /tasks count[/span
int gi; //全域陣列索引。
void *workThread(void *args){
int ai;///作業陣列元素的內部索引。
while(1){
pthread_mutex_lock(&mutexQueue)。
while(tc==0){
pthread_cond_wait(&condQueue,&mutexQueue); /wait for signal if tasks count = 0..
}
ai=gi。
if(gi==127)gi=0; else gi ;
tc--;
pthread_mutex_unlock(&mutexQueue)。
printf("%s
",textArr[ai])。
//然后處理websocket資料。
}
}
void *generalThread(void *args){
const char chrs[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"/span>。//chars fo隨機文本生成。
int ai=0;
srand(time(NULL))。
while(1){
for(int i=0; i<23; i )textArr[ai][i]=chrs[rand()%61];//generating data instead of websocket data /span>
textArr[ai][23]=''/span>。
tc 。
pthread_cond_signal(&condQueue); //Send signal for thread to begin work with data[/span]。
if(ai==127)ai=0; else ai ;
}
}
int main(int argc,char *argv[]){
pthread_attr_init(&attrd)。
pthread_attr_setdetachstate(&attrd,PTHREAD_CREATE_DETACHED)。
pthread_t gt,wt[32] 。
for(int i=0; i< 32;i )pthread_create(&wt[i],&attrd,&workThread,NULL)
pthread_create(>,NULL,&GeneralThread,NULL)。
pthread_join(gt,NULL)。
return 0;
uj5u.com熱心網友回復:
首先一些資訊:
原理
一些實作,特別是在多處理器上,當條件變數在不同處理器上同時發出信號時,有時可能導致多個執行緒被喚醒。
原理通過條件信號進行多重喚醒
在多處理器上,pthread_cond_signal()的實作可能無法避免一個以上的執行緒在一個條件變數上被阻塞時的解鎖。
...
其結果是,由于對pthread_cond_wait()或pthread_cond_timedwait()的一次呼叫,會有多個執行緒從呼叫pthread_cond_signal()回傳。這種效果被稱為 "假性喚醒"。請注意,這種情況是可以自我糾正的,因為這樣被喚醒的執行緒數量是有限的;例如,在上面的事件序列阻塞后,下一個呼叫pthread_cond_wait()的執行緒。
到目前為止,你的workThread中的代碼是適當的同步的(但是你應該把printf也放在同步部分),但是你的generalThread中的代碼完全沒有同步。用鎖/解鎖來封裝while回圈中的代碼。
在這種情況下,第一個被喚醒的執行緒必須在指定的mutex上獲得一個鎖,這個鎖將被另一個執行緒或generalThread所擁有。在mutex被解鎖之前,該執行緒會被阻塞(不管它被喚醒的原因是什么)。在獲取之后,它就擁有了這個mutex,所有其他執行緒都將被阻塞,generalThread包括在內。
注意:pthread_cond_wait在進入等待狀態時隱含地解鎖了指定的mutex,并且在喚醒時它試圖獲取指定mutex上的鎖。
uj5u.com熱心網友回復:
在tc 中添加一個mutex鎖,可以完全糾正我的程式:
void *generalThread(void *args) {
const char chrs[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ;
int ai=0;
srand(time(NULL))。
while(1){
for(int i=0; i<23;i )textArr[ai][i]=chrs[rand()%61] 。
textArr[ai][23]=''/span>。
pthread_mutex_lock(&mutexQueue); // this has been added
tc 。
pthread_mutex_unlock(&mutexQueue); // this has been added
pthread_cond_signal(&condQueue)。
if(ai==127)ai=0; else ai ;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/308331.html
標籤:
