[英]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 < 4
的conddone
變量)。 如果您的工作線程之一在“回調”線程執行了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.