2012-05-06 64 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);