Linux 使用pthreads在多核上并行化数据处理
我的目标是通过使用多个工作线程来处理多个内核上的数据,然后在主线程中进一步处理结果。我在linux上工作,我想使用pthreads。我创建了一个简单的示例来学习如何正确地执行此操作。我有一个名为“回调”的主线程和4个工作线程。其思想是主线程通知工作线程开始处理,然后4个线程在它们完成时通知主线程,主线程在所有4个线程通知它们完成后退出。我希望4个工作线程能够并行运行,所以我不希望这些线程中有任何线程等待其他线程。在我的示例中,我尝试让每个线程睡眠不同的持续时间(1、2、3和4秒),并认为代码将在4秒后退出(即工作线程4等待4秒) 由于某些原因,我的代码不正确,它总是立即退出,打印以下内容:Linux 使用pthreads在多核上并行化数据处理,linux,multithreading,pthreads,worker,Linux,Multithreading,Pthreads,Worker,我的目标是通过使用多个工作线程来处理多个内核上的数据,然后在主线程中进一步处理结果。我在linux上工作,我想使用pthreads。我创建了一个简单的示例来学习如何正确地执行此操作。我有一个名为“回调”的主线程和4个工作线程。其思想是主线程通知工作线程开始处理,然后4个线程在它们完成时通知主线程,主线程在所有4个线程通知它们完成后退出。我希望4个工作线程能够并行运行,所以我不希望这些线程中有任何线程等待其他线程。在我的示例中,我尝试让每个线程睡眠不同的持续时间(1、2、3和4秒),并认为代码将在
thread 3 start (sleeping 3000 ms)
thread 2 start (sleeping 2000 ms)
thread 1 start (sleeping 1000 ms)
thread 4 start (sleeping 4000 ms)
thread 1 stop
thread 2 stop
thread 3 stop
thread 4 stop
Main(): Waited on 5 threads. Done.
因此线程看起来确实以正确的顺序退出,但程序运行不需要4秒
这是怎么回事?我已将代码粘贴到下面
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
// based on https://computing.llnl.gov/tutorials/pthreads/#ConditionVariables
#define DUR 1000
#define NUM_THREADS 5
int state = 0;
pthread_mutex_t mutex;
pthread_cond_t conddone;
pthread_cond_t condwork;
void* callback(void* t) {
// signal worker threads to start work
pthread_mutex_lock(&mutex);
pthread_cond_broadcast(&condwork);
pthread_mutex_unlock(&mutex);
// wait for worker threads to finish
pthread_mutex_lock(&mutex);
while (state < 4)
pthread_cond_wait(&conddone, &mutex);
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
void* worker(void* t) {
long id = (long)t;
// wait for signal from callback to start doing work
pthread_mutex_lock(&mutex);
pthread_cond_wait(&condwork, &mutex);
pthread_mutex_unlock(&mutex);
// do work
printf("thread %d start (sleeping %d ms)\n", id, id * DUR);
usleep(id * DUR);
printf(" thread %d stop\n", id);
// tell callback we're done
pthread_mutex_lock(&mutex);
state++;
pthread_cond_signal(&conddone);
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
int i, rc;
pthread_t threads[5];
pthread_attr_t attr;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init (&condwork, NULL);
pthread_cond_init (&conddone, NULL);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&threads[0], &attr, callback, (void *)0);
pthread_create(&threads[1], &attr, worker, (void *)1);
pthread_create(&threads[2], &attr, worker, (void *)2);
pthread_create(&threads[3], &attr, worker, (void *)3);
pthread_create(&threads[4], &attr, worker, (void *)4);
for (i=0; i<NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
printf ("Main(): Waited on %d threads. Done.\n", NUM_THREADS);
pthread_attr_destroy(&attr);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&condwork);
pthread_cond_destroy(&conddone);
pthread_exit(NULL);
}
#包括
#包括
#包括
//基于https://computing.llnl.gov/tutorials/pthreads/#ConditionVariables
#定义DUR 1000
#定义NUM_线程5
int state=0;
pthread_mutex_t mutex;
pthread_cond_t cond done;
pthread_u cond_t condwork;
void*callback(void*t){
//发出工作线程开始工作的信号
pthread_mutex_lock(&mutex);
pthread_cond_广播(&condwork);
pthread_mutex_unlock(&mutex);
//等待工作线程完成
pthread_mutex_lock(&mutex);
而(状态<4)
pthread_cond_wait(&conddone,&mutex);
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
void*worker(void*t){
长id=(长)t;
//等待回调信号开始工作
pthread_mutex_lock(&mutex);
pthread_cond_wait(&condwork,&mutex);
pthread_mutex_unlock(&mutex);
//工作
printf(“线程%d开始(休眠%d毫秒)\n”,id,id*DUR);
usleep(id*DUR);
printf(“线程%d停止\n”,id);
//告诉callback我们完成了
pthread_mutex_lock(&mutex);
状态++;
pthread_cond_信号(&conddone);
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
int main(int argc,char*argv[])
{
int i,rc;
pthread_t线程[5];
pthread_attr_t attr;
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&condwork,NULL);
pthread_cond_init(&conddone,NULL);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,pthread_CREATE_JOINABLE);
pthread_创建(&threads[0],&attr,callback,(void*)0);
pthread_create(&threads[1],&attr,worker,(void*)1);
pthread_create(&threads[2],&attr,worker,(void*)2);
pthread_create(&threads[3],&attr,worker,(void*)3);
pthread_create(&threads[4],&attr,worker,(void*)4);
对于(i=0;i而言,您当前的问题只是usleep()
睡眠时间是微秒而不是毫秒,因此线程睡眠时间是您希望它们睡眠时间的千分之一
不过,您确实有另一个问题:您的condwork
条件变量没有与共享状态上的谓词配对(例如conddone
变量的谓词state<4
)。如果您的一个工作线程在“回调”之后执行pthread\u cond\u wait()
线程已执行pthread\u cond\u broadcast()
,工作线程将无限期等待
您可以通过将状态
变量初始化为-1
来解决此问题:
int state = -1;
让您的工作人员等待谓词状态<0
:
// wait for signal from callback to start doing work
pthread_mutex_lock(&mutex);
while (state < 0)
pthread_cond_wait(&condwork, &mutex);
pthread_mutex_unlock(&mutex);
// signal worker threads to start work
pthread_mutex_lock(&mutex);
state = 0;
pthread_cond_broadcast(&condwork);
pthread_mutex_unlock(&mutex);