2012-05-06 110 views
1

對於作業,我們已經給出了浴室同步問題。我一直在努力想弄清楚如何開始。當一個人進入洗手間(personEnterRestrrom函數)時,我想要做什麼,如果他們是女性,並且沒有男性在他們進入的洗手間,如果不是,他們進入排隊等候的女性。我想爲男性做同樣的事情。我試圖實現一個擁有線程的隊列,但無法使其工作。然後在personLeavesRestroom函數中。如果一個人離開,如果沒有人離開浴室,另一個隊列開始。這裏是我的代碼,我知道我很遙遠,我確實需要一些指導,並且不太熟悉信號量。浴室同步和線程隊列

//declarations 
pthread_mutex_t coutMutex; 
int menInBath; 
int womanInBath; 
int menWaiting; 
int womenWaiting; 
queue<pthread_mutex_t>men; 
queue<pthread_mutex_t>women; 


personEnterRestroom(int id, bool isFemale) 
{ 
    // LEAVE THESE STATEMENTS             
    pthread_mutex_lock(&coutMutex); 
    cout << "Enter: " << id << (isFemale ? " (female)" : " (male)") << endl; 
    pthread_mutex_unlock(&coutMutex); 

    // TODO: Complete this function           
if(isFemale && menInBath<=0) 
    { 
    womanInBath++; 
    } 
else if(isFemale && menInBath>0) 
{ 
    wait(coutMutex); 
    women.push(coutMutex); 
} 
else if(!isFemale && womanInBath<=0) 
{ 
    menInBath++; 
} 
else 
{ 
    wait(coutMutex); 
    men.push(coutMutex); 
} 

}

void 
    personLeaveRestroom(int id, bool isFemale) 
    { 
    // LEAVE THESE STATEMENTS             
    pthread_mutex_lock(&coutMutex); 
    cout << "Leave: " << id << (isFemale ? " (female)" : " (male)") << endl; 
    pthread_mutex_unlock(&coutMutex); 

    if(isFemale) 
    womanInBath--; 
    if(womanInBath==0) 
    { 
     while(!men.empty()) 
     { 
      coutMutex=men.front(); 
      men.pop(); 
      signal(coutMutex); 
     } 
    } 

} 
+0

我想你想你的隊列中包含的ID,而不是線程。 –

+0

實際上,只要持有一個布爾值來表示當前廁所中的人是男性還是女性,然後只是一個計數器,就可以使這一點變得更簡單。你需要在布爾值和計數器周圍同步鎖定,所以你不需要持有一個男人或女人的計數器,除非你想等待一個隊列,在這種情況下,你可以使用某種形式的隊列,允許進入洗手間 – EdChum

回答

1

如果您正在尋找FIFO互斥量,這個可以幫助你:

你會需要:
互斥pthread_mutex_t mutex),
陣列條件變量std::vector<pthread_cond_t> cond
用於存儲線程ID的隊列std::queue<int> fifo)。

假設有N線程ID爲0N-1。然後fifo_lock()fifo_unlock()看起來是這樣的(僞):

fifo_lock() 
    tid = ID of this thread; 
    mutex_lock(mutex); 
    fifo.push(tid); // puts this thread at the end of queue 

    // make sure that first thread in queue owns the mutex: 
    while (fifo.front() != tid) 
     cond_wait(cond[tid], mutex); 

    mutex_unlock(mutex); 

fifo_unlock() 
    mutex_lock(mutex); 
    fifo.pop(); // removes this thread from queue 

    // "wake up" first thread in queue: 
    if (!fifo.empty()) 
     cond_signal(cond[fifo.front()]); 

    mutex_unlock(mutex);