疑问:关于Exhibit的编号# Immigration - 落地生根
K*y
1 楼
(原贴见http://www.mitbbs.com/article/JobHunting/32331973_3.html)
3: 实现两个函数: H() and O(), 这两个函数会被多线程调用。当一个线程调用H或O时
,如果当前已经有至少两个线程call H和一个线程call O。那么让两个call H和一个
call O的线程返回(产生一个水分子),其他的都block。
多线程我不熟,pthread里没有现成的semaphore,所以习惯用condition variable。闭
门造车写了下面这样一个解法,显然不如版上各位给的代码简洁。但是这里有个bug我
想不明白,请教一下各位:
我的基本想法是,如果三个原子里最后一个就位的是H,则signal O,O再signal另一个
H;如果最后一个是O,则signal一个H,这个H再signal另一个H。为了区分H函数的两种
情况,我起初用了个bool signalNextH,但是会出现死锁。改成int来计数就过了(下
面的代码)。从这个症状来看,似乎是有两个O原子同时发出了signal,所以
signalNextH要用counter,不能用简单的bool。可是为什么会有这种情况,从O发出
signal到H wakeup之间不应该没有机会让另一个O插队吗?多谢!
void H2OHelper::H()
{
pthread_mutex_lock(&mutex);
++hCounter;
if (hCounter >= 2 && oCounter >= 1)
{
pthread_cond_signal(&cond_Havailable);
pthread_mutex_unlock(&mutex);
}
else
{
while (hCounter < 2 || oCounter < 1)
pthread_cond_wait(&cond_Oavailable, &mutex);
if (signalNextH > 0)
{
--signalNextH;
pthread_cond_signal(&cond_Oavailable);
}
else
{
hCounter -= 2;
oCounter -= 1;
}
pthread_mutex_unlock(&mutex);
}
}
void H2OHelper::O()
{
pthread_mutex_lock(&mutex);
++oCounter;
if (hCounter >= 2 && oCounter >= 1)
{
++signalNextH;
pthread_cond_signal(&cond_Oavailable);
pthread_mutex_unlock(&mutex);
}
else
{
while (hCounter < 2 || oCounter < 1)
pthread_cond_wait(&cond_Havailable, &mutex);
pthread_cond_signal(&cond_Oavailable);
pthread_mutex_unlock(&mutex);
}
}
3: 实现两个函数: H() and O(), 这两个函数会被多线程调用。当一个线程调用H或O时
,如果当前已经有至少两个线程call H和一个线程call O。那么让两个call H和一个
call O的线程返回(产生一个水分子),其他的都block。
多线程我不熟,pthread里没有现成的semaphore,所以习惯用condition variable。闭
门造车写了下面这样一个解法,显然不如版上各位给的代码简洁。但是这里有个bug我
想不明白,请教一下各位:
我的基本想法是,如果三个原子里最后一个就位的是H,则signal O,O再signal另一个
H;如果最后一个是O,则signal一个H,这个H再signal另一个H。为了区分H函数的两种
情况,我起初用了个bool signalNextH,但是会出现死锁。改成int来计数就过了(下
面的代码)。从这个症状来看,似乎是有两个O原子同时发出了signal,所以
signalNextH要用counter,不能用简单的bool。可是为什么会有这种情况,从O发出
signal到H wakeup之间不应该没有机会让另一个O插队吗?多谢!
void H2OHelper::H()
{
pthread_mutex_lock(&mutex);
++hCounter;
if (hCounter >= 2 && oCounter >= 1)
{
pthread_cond_signal(&cond_Havailable);
pthread_mutex_unlock(&mutex);
}
else
{
while (hCounter < 2 || oCounter < 1)
pthread_cond_wait(&cond_Oavailable, &mutex);
if (signalNextH > 0)
{
--signalNextH;
pthread_cond_signal(&cond_Oavailable);
}
else
{
hCounter -= 2;
oCounter -= 1;
}
pthread_mutex_unlock(&mutex);
}
}
void H2OHelper::O()
{
pthread_mutex_lock(&mutex);
++oCounter;
if (hCounter >= 2 && oCounter >= 1)
{
++signalNextH;
pthread_cond_signal(&cond_Oavailable);
pthread_mutex_unlock(&mutex);
}
else
{
while (hCounter < 2 || oCounter < 1)
pthread_cond_wait(&cond_Havailable, &mutex);
pthread_cond_signal(&cond_Oavailable);
pthread_mutex_unlock(&mutex);
}
}