2012-11-22 47 views
0

我有兩個線程。 一個從隊列中讀取數據。我不希望它運行一段時間(1)閱讀,所以我想給它一個條件變量的每個循環:pthread_cond_wait和pthread_cond_signal的性能

while(1){ 
    while queue is not empty 
     wait(cond) 
     pop() 
} 

代替:

while(1){ 
    while queue is not empty 
     pop 
} 

和線程如果我使用等待和信號方法,那麼該線程需要通過發信號通知彈出線程每次(!)它推動 問題是什麼更好使用? 如果隊列大部分不是空的,那麼發送信號就毫無價值(或者不是?),因爲彈出線程並未等待,我擔心會降低性能。 但是,如果隊列的時間爲空時間的一半,那麼在第二個方法中循環播放可能是一個繁忙的等待。

我希望這裏有人會通過不合格的事實,將信號發送到未在其上等待的線程仍然是確定

感謝

+2

這些操作的性能是否有影響取決於你的程序在做什麼,所以衡量表現的唯一理智的事情就是衡量表現。 – PlasmaHH

+0

鎖在哪裏? – chill

+0

此外,使用條件變量來製作推送和彈出原子的必要性通常是設計要求,而不是您可以決定不執行的操作。 –

回答

0

首先只是爲了確保消除我的恐懼,pthread_cond_signal不在signal(2)意義上不發送signal。它只是標記條件變量並釋放等待它的任何變量。因此,如果您在消費過程調用良好之前致電pthread_cond_signal,那將會被忽略。

其次,是pthread_cond_wait快還是慢?這得看情況。你可以使用它很差,你可以很好地使用它。如果你使用它很差,我相信它會表現非常糟糕。如果你只是在真正需要的時候等待,我認爲它會表現得很好。因此,由於您需要持有一個互斥量才能使用條件變量,因此您可能需要檢查此時是否有數據(並將此互斥量用作同步點)。

爲隊列數據結構的想法:

struct q { 
    struct qe *h; 
    struct qe *t; 

    pthread_mutex_t m; 
    pthread_cond_t c; 
    int len; 
}; 

消費者(假設你只有一個消費者,如果您有多個需要繞頭檢查鎖):

void *consumer(void*arg) { 
    struct q *q = arg; 

    while(1) { 
     pthread_mutex_lock(&q->m); 
     if(q->h == NULL) 
      pthread_cond_wait(&q->c, &q->m); 
     /* We hold the mutex when we exit pthread_cond_wait */ 
     pthread_mutex_unlock(&q->m); /* we can make the check without the mutex */ 
     while(q->h != NULL) { 
      pthread_mutex_lock(&q->m); /* but we need it to modify */ 
      pop(); 
      pthread_mutex_unlock(&q->m); 
      /* Process data */ 
     } 
    } 
} 

生產者:

void *producer(void*arg) { 
    int i; 
    struct q *q = arg; 
    while(1) { 
     pthread_mutex_lock(&q->m); 
     push(q, some_data); 
     if(q->h == q->t) /* only one element */ 
      pthread_cond_signal(&q->c); 
     pthread_mutex_unlock(&q->m); 
    }  
    return NULL; 
} 
相關問題