Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 使用pthreads在多核上并行化数据处理_Linux_Multithreading_Pthreads_Worker - Fatal编程技术网

Linux 使用pthreads在多核上并行化数据处理

Linux 使用pthreads在多核上并行化数据处理,linux,multithreading,pthreads,worker,Linux,Multithreading,Pthreads,Worker,我的目标是通过使用多个工作线程来处理多个内核上的数据,然后在主线程中进一步处理结果。我在linux上工作,我想使用pthreads。我创建了一个简单的示例来学习如何正确地执行此操作。我有一个名为“回调”的主线程和4个工作线程。其思想是主线程通知工作线程开始处理,然后4个线程在它们完成时通知主线程,主线程在所有4个线程通知它们完成后退出。我希望4个工作线程能够并行运行,所以我不希望这些线程中有任何线程等待其他线程。在我的示例中,我尝试让每个线程睡眠不同的持续时间(1、2、3和4秒),并认为代码将在

我的目标是通过使用多个工作线程来处理多个内核上的数据,然后在主线程中进一步处理结果。我在linux上工作,我想使用pthreads。我创建了一个简单的示例来学习如何正确地执行此操作。我有一个名为“回调”的主线程和4个工作线程。其思想是主线程通知工作线程开始处理,然后4个线程在它们完成时通知主线程,主线程在所有4个线程通知它们完成后退出。我希望4个工作线程能够并行运行,所以我不希望这些线程中有任何线程等待其他线程。在我的示例中,我尝试让每个线程睡眠不同的持续时间(1、2、3和4秒),并认为代码将在4秒后退出(即工作线程4等待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);