簡體   English   中英

使用pthread並行化多個內核上的數據處理

[英]parallelize data processing on multiple cores using pthreads

我的目標是通過使用多個工作線程來處理多個內核上的數據,然后在主線程中進一步處理結果。 我在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);
} 

你眼前的問題僅僅是usleep()休眠微秒毫秒所以你的線程都睡了,你打算在他們的時間千分之一。

你有另外一個問題,雖然:你condwork條件變量不超過共享狀態的謂詞(如謂詞配對state < 4conddone變量)。 如果您的工作線程之一在“回調”線程執行了pthread_cond_wait()之后執行了pthread_cond_broadcast() ,則工作線程將無限期等待。

您可以通過將state變量初始化為-1來解決此問題:

int state = -1;

並讓您的工作人員等待謂詞state < 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);

並通過將狀態設置為0,使“回調”向工作人員發出信號:

// signal worker threads to start work 

pthread_mutex_lock(&mutex);
state = 0;
pthread_cond_broadcast(&condwork);
pthread_mutex_unlock(&mutex);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM