簡體   English   中英

pthread_mutex_wait多個生產者和消費者

[英]pthread_mutex_wait multiple producer and consumer

我所經歷的這個這個鏈接。 基本上,他們正在討論為什么經典的單線程生產者使用者設計(帶有signalwait不適用於多生產者方案)。 我有一個疑問困擾着我-

作者的論點
考慮參考代碼

char queue[MAX];  //global
int head = 0, tail = 0; //global
struct cv not_full, not_empty;
struct lock qlock;

void produce(char data) {
  acquire(&qlock);
  if ((head + 1) % MAX  ==  tail) {
    wait(&not_full, &qlock);   //line 1
  }
  queue[head] = data; //line 2
  head = (head + 1) % MAX;
  notify(&not_full);
  release(&qlock);
}

char consume(void) {
  acquire(&qlock);
  if (tail == head) {
    wait(&not_empty, &qlock);
  }
  e = queue[tail];
  tail = (tail + 1) % MAX;
  notify(&not_empty);
  release(&qlock);
  return e;
}

在上面的代碼中,如果有兩個生產者,則單個生產者將在兩個生產者線程中woken up line 1 (當隊列未滿時)。 因此,兩個生產者都可以添加到隊列中,從而導致隊列溢出。

我的疑問
一種。 我們使用互斥鎖保護隊列。 因此,即使在多個生產者線程上喚醒wait ,也只有一個生產者仍具有互斥鎖-因此從邏輯上講,只有一個生產者“擁有”權限要添加到隊列中。 因為當我們擺脫wait我們將擁有互斥量。

CAVET
我使用POSIX互斥鎖,cond var作為參考。 但是,我看不到用POSIX作為參考標准寫的文章。


我對wait理解特別是pthread_cond_wait是否正確? 在多個生產者的情況下,代碼的完整性仍然得以保持。

作者在文章的結尾部分提到了wait()和notify()的語義

notify(cv)喚醒當前正在該cv上等待的所有線程

因此,您對wait的理解是不正確的, notify意味着在posix中為pthread_cond_broadcast

此外,pthread_cond_signal文檔規定

pthread_cond_signal()調用可解除對至少一個在指定條件變量cond上阻塞的線程的解除阻塞(如果在cond上阻塞了任何線程)。

這仍然與您的“僅一個生產者”假設不同。

如作者所示,以上代碼的完整性無法由多個生產者維護。

編輯:

條件變量 wait偽代碼可能看起來像

void wait (condition *cv, mutex *mx) 
{
    mutex_acquire(&c->listLock);  /* protect the queue */
    enqueue (&c->next, &c->prev, thr_self()); /* enqueue */
    mutex_release (&c->listLock); /* we're done with the list */

    /* The suspend and release_mutex() operation should be atomic */
    release_mutex (mx));
    thr_suspend (self);  /* Sleep 'til someone wakes us */

    <-------- notify executes somewhere else

    mutex_acquire (mx); /* Woke up -- our turn, get resource lock */
    return;
}

signal期間,隊列中處於suspend狀態的至少一個線程被喚醒。 但是pthread保證它只會是一個 現在它們可以運行了。 但是他們仍然需要獲取鎖,以確保彼此之間的互斥。

因此,當第一個釋放互斥量時,第二個釋放互斥量,依此類推。

這意味着喚醒的生產者將一個接一個地執行

queue[head] = data; //line 2
head = (head + 1) % MAX;
notify(&not_full);
release(&qlock);

暫無
暫無

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

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