2012-02-28 97 views
4

我不確定標題是否反映了我在這裏問的問題,但這是最好的,我可以在沒有非常冗長的標題的情況下完成。我試圖在pthreads中實施worker thread型號。我想從main函數中產生一組線程,之後main線程將作業委託給worker,並等待所有線程完成,然後再爲他們分配下一個任務(實際上,要求是將線程安排在一個塊內如CUDA編程模型,但在CPU上,儘管它與當前問題無關)。 job數組用於指示每個線程的作業類型。目前,我已經實施了這種使用信號量來強制等待。我正在尋找方法,以便線程能夠在需要時進入睡眠狀態並喚醒,而不是連續輪詢。喚醒個人線程,而不是忙於在pthreads中等待

每個線程執行的功能

volatile int jobs[MAX_THREADS]; // global job indicator array 
sem_t semaphore;    // semaphore to indicate completion 
thread_execute(void *args) 
{ 
    tid = get_id(args); 
    while(jobs[tid] != -1) 
    { 
    if(jobs[tid] == 0) continue; // no job 
    if(jobs[tid] == JOBS_1) 
    { 
     jobs1(); 
     jobs[tid] = 0; // go back to idle state 
     sem_post(&semapahore); 
    } 
    if(jobs[tid] == JOBS_2) 
    { 
     jobs2(); 
     jobs[tid] = 0; // go back to idle state 
     sem_post(&semapahore); 
    } 
    } 

    pthread_exit(NULL); 
} 

主要功能如下

int main() 
{ 
    sem_init(&semaphore, 0, 0); 
    jobs[0...MAX_THREADS] = 0; 
    spawn_threads(); 

    // Dispatch first job 
    jobs[0...MAX_THREADS] = JOBS_1; 
    int semvalue = 0; 
    while (semvalue < MAX_THREADS) // Wait till all threads increment the semaphore 
    sem_getvalue(&sempaphore, &semvalue); 

    sem_init(&semaphore, 0, 0); // Init semaphore back to 0 for the next job 
           // I'm actually using diff. semaphores for diff. jobs 
    jobs[0...MAX_THREADS] = JOBS_2; 
    while (semvalue < MAX_THREADS) 
    sem_getvalue(&sempaphore, &semvalue); 

    jobs[0...MAX_THREADS] = -1; // No more jobs 
    pthread_join(); 
} 

這種實現的問題是,main線程繁忙等待所有工作線程完成和工作線程也不斷地輪詢作業數組以檢查新作業。當線程進入睡眠狀態並在需要的時候喚醒時,是否有更好的方法來處理信號處理程序的線路,並使用pthread_kill(),但是對於單獨的信號處理程序來說這是一種混亂。

+0

信號燈被阻塞 - 不應該有忙等待!乍一看,這看起來像線程微觀管理:(( – 2012-02-28 19:49:21

+0

)你可以擺脫作業陣列和生產者 - 消費者隊列作業對象到線程池 - 這是做這種工作的常用方式。類可以包含一個emum來告訴線程該做什麼,(枚舉Ecommand {Ejob1,Ejob2,Eterminate})。然後,您只需要一個信號量(用於線程等待並計數隊列項)和一個互斥量以保護隊列不受多個訪問的影響 – 2012-02-28 19:55:54

+0

我的確需要微管理線程,而典型的生產者消費者模型並不適合此目的,但訪問作業隊列的基本思想在這裏也是有效的。@Tudor給出的代碼是我在找的東西,謝謝! – user1135552 2012-02-28 21:20:02

回答

3

您可以使用conditional variable使線程進入休眠狀態,直至發出信號。

volatile int jobs[MAX_THREADS]; // global job indicator array 
pthread_cond_t th_cond;  // threads wait on this 
pthread_mutex_t th_mutex; // mutex to protect the signal 
int busyThreads = MAX_THREADS; 

pthread_cond_t m_cond;  // main thread waits on this 
pthread_mutex_t m_mutex; // mutex to protect main signal 

thread_execute(void *args) 
{ 
    tid = get_id(args); 
    while(jobs[tid] != -1) 
    { 
    if(jobs[tid] == 0) continue; // no job 
    if(jobs[tid] == JOBS_1) 
    { 
     jobs1(); 
     jobs[tid] = 0; // go back to idle state 
     pthread_mutex_lock(&th_mutex);  
      pthread_mutex_lock(&m_mutex); 
      --busyThreads;      // one less worker 
      pthread_cond_signal(&m_cond);  // signal main to check progress 
      pthread_mutex_unlock(&m_mutex); 
     pthread_cond_wait(&th_cond, &th_mutex); // wait for next job 
     pthread_mutex_unlock(&th_mutex);  
    } 
    if(jobs[tid] == JOBS_2) 
    { 
     jobs2(); 
     jobs[tid] = 0; // go back to idle state 
     pthread_mutex_lock(&th_mutex); 
     --busyThreads; 
     pthread_cond_wait(&th_cond, &th_mutex); 
     pthread_mutex_unlock(&th_mutex); 
    } 
    } 

    pthread_exit(NULL); 
} 

然後在主:

int main() 
{ 
    sem_init(&semaphore, 0, 0); 
    jobs[0...MAX_THREADS] = 0; 
    spawn_threads(); 

    // Dispatch first job 
    jobs[0...MAX_THREADS] = JOBS_1; 
    int semvalue = 0; 

    pthread_mutex_lock(&m_mutex); 
    while(busyThreads > 0)  // check number of active workers 
     pthread_cond_wait(&m_cond, &m_mutex); 
    pthread_mutex_unlock(&m_mutex); 

    busyThreads = MAX_THREADS; 
    pthread_mutex_lock(&th_mutex); 
    pthread_cond_broadcast(&th_cond); // signal all workers to resume 
    pthread_mutex_unlock(&th_mutex); 

    // same for JOBS_2; 

    jobs[0...MAX_THREADS] = -1; // No more jobs 
    pthread_join(); 
} 
+0

謝謝!!這比一個忙碌的等待要好得多:) – user1135552 2012-02-28 21:23:12

+0

@ user1135552:你測試過了嗎?我把它寫在頭頂上,所以我不確定它是不是100%正確。 – Tudor 2012-02-28 21:35:44

+0

我用你的代碼@Tudor修改了我的實現。它完美的工作,現在它發現模式比繁忙的等待實現快30%!謝謝你:) – user1135552 2012-02-28 22:12:52