这是问题所在。洗手间一次可以由男性或女性使用。如果男性或女性在给定时间进入洗手间,则异性不能进入洗手间并且必须等待。一旦所有女性都出局,那么男性可以进入。所以,这是我的解决方案:
我想使用信号量和互斥量在线程之间执行同步。我还不清楚如何实现它。 以下是我的想法:
所以首先,我检查一下这个过程是什么性别,然后我检查一下反对性的角度是否大于一。如果没有,我让他们进入洗手间。但如果洗手间已经有反对性行为的成员,我需要让这个过程等待并让它入睡。
如何让这个过程完全入睡?我找了一些例子,但仍然不知道该怎么做。
使用wait()
和signal()
的功能签名的示例非常有用。
答案 0 :(得分:0)
“创建一个信号量来计算洗手间的人数。一个 每个性别信号量male_in_restroom;信号量female_in_restroom; 排队等候男性,排队等候女性,“
没有意义。信号量值的目的是指示资源是否可用。 如果值为零,则资源不可用。如果该值大于零,则该资源可用。因此,如果您通过使用资源以某种方式设法增加 sem计数,那么信号量有什么用途呢?
首先,我检查过程中的性别,然后检查是否有 反对性的semphore大于一。如果不是我让他们 进入洗手间。
不,不,不!你有低音笨蛋。这强调了一点:信号量不是用于存储任意值。
您的各种计数等是正常变量,而不是信号量,但是,您必须使用互斥锁/信号量/条件变量(最可能是:互斥+条件变量)来控制对它们的访问
另外,我不知道为什么你认为跟踪有多少人在等待是有用的或重要的。
答案 1 :(得分:0)
这看起来很有趣,所以我写了一些代码。虽然没有测试过,所以可能搞砸了一些东西,但它足以说明我的想法。
typedef enum {
none = -1,
male = 0,
female = 1
} sex_t;
class Human {
public:
const sex_t id;
Human(sex_t id_) : id(id_) {assert(id != none);}
};
class Restroom {
tbb::spin_mutex door_mutex;
tbb::atomic<size_t> num_waiting;
HANDLE opposite_sex_can_enter;
// these two variables need not be atomic, they're not accessed concurrently
sex_t current_occupying_sex;
size_t num_visitors;
public:
Restroom() : current_occupying_sex(none), num_visitors(0) {
num_waiting = 0;
opposite_sex_can_enter = CreateEvent(0, TRUE, FALSE, 0);
}
void enter(const Human& h) {
tbb::spin_mutex::scoped_lock lock(door_mutex);
// this prevents any two humans trying to open the door (in any direction) at the same time :)
if(current_occupying_sex == none) {
// you're the first one in, so update the 'restroom id' and enter
assert(num_visitors == 0 && num_waiting == 0);
// if the knowledge of SetEvent has not propagated all the way yet and the same sex
// person happens to walk into the restroom again, opposite sex people need to know
// that they were slow and will need to wait again
ResetEvent(opposite_sex_can_enter);
current_occupying_sex = h.id;
++num_visitors;
} else if(h.id == current_occupying_sex) {
// you're not the first one in, but you're of the same sex, so you can just walk in
assert(num_visitors > 0);
++num_visitors;
} else {
// you're not the first one in and you're of opposite sex, so you'll need to wait
// first, let go of the door, you're not getting in :)
lock.release();
// then join the rest of the opposite sex people waiting
++num_waiting;
WaitForSingleObject(opposite_sex_can_enter);
--num_waiting;
if(num_waiting == 0) {
ResetEvent(opposite_sex_can_enter);
}
enter(h);
}
}
void exit() {
tbb::spin_mutex::scoped_lock lock(door_mutex);
if(--num_visitors == 0) {
current_occupying_sex = none;
SetEvent(opposite_sex_can_enter);
// fairness can be imposed here, meaning that if you're the last say, male
// to walk out, you can check if females are waiting and switch the
// restroom sex id to female. The logic of enter() will change a little bit, but not radically.
}
}
};