【发布时间】:2021-11-09 00:40:13
【问题描述】:
我正在编写一个程序,它从 websocket 接收数据并在线程池中处理这些数据。 当处理器有 2 个或更多内核时,我对 pthread_cond_wait 有问题。在不同内核上运行的所有线程接收到 pthread_cond_signal 信号后。例如,如果我有 2 个内核,那么信号将一次到达 2 个线程,它们位于这两个内核上。如果我有单核处理器,一切都很好。 我必须做什么才能让程序在多核处理器上正常工作?这样只有一个线程接收到开始工作的信号。 我用生成随机文本数据而不是 websocket 数据编写了我的代码示例。
#include<stdio.h>
#include<stdlib.h>
#include<cstring>
#include<pthread.h>
#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
int gi; //global array index
void *workThread(void *args){
int ai;//internal index for working array element
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\r\n",textArr[ai]);
// then work with websocket data
}
}
void *generalThread(void *args){
const char chrs[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; //chars fo random text generation
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
textArr[ai][23]='\0';
tc++;
pthread_cond_signal(&condQueue); //Send signal for thread to begin work with data
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;
}
【问题讨论】:
-
generalThread有两个问题。首先,它应该在更新tc和调用pthread_cond_signal时锁定互斥锁。其次,当循环缓冲区填满时,它应该sleep。按照现在的代码,generalThread可以比工作人员删除字符串更快地向缓冲区添加字符串。 -
@user3386109 谢谢。但是如果我检查 tc!=0 两个线程都将返回 true,因为它们工作相同。
-
@user3386109 当 websocket 工作时,缓冲区填满的速度相当慢。不需要睡觉。一般来说,互斥锁如何帮助线程立即接收信号?
-
@BadMan 在写下我现在已删除的评论后,我注意到您正在检查
tc!=0,因为while (tc==0)循环。所以已经编写了代码来处理虚假唤醒。如果两个线程唤醒,只有一个线程应该能够获取互斥锁。所以只有一个线程应该看到tc!=0。您可以通过在每次调用pthread_cond_signal后在generalThread中调用sleep来验证这一点。 -
代码中似乎缺少的另一件事是initialization of the mutex and condition variable。
标签: c multithreading pthreads threadpool mutex