所以练习的描述:
你有这个餐厅,其中有N个点,你可以要求一部分薯条。每个点都有M个部分。有1个frycheff。当订单点有2个部分时,它会警告cheff它需要重新填充。 cheff按FIFO的顺序传送部分。
我们制作了这个伪代码:
init {
Semafoor[] mutex;
Condition[] cond_point = new Condition[N];
int[] portions = new int[N];
ArrayList<int> waitline = new ArrayList<int>();
for(int i = 0; i < N; i++) {
mutex[i] = new Semafoor(1);
portions[i] = M;
}
}
point(int n) {
while(1) {
mutex[n].acquire();
if(portions[n] == 0) {
cond_point[n].wait(mutex[n]);
}
else if(portios[n] == 2) {
waitline.add(n);
}
portions[n]--;
mutex[n].release();
}
}
frycheff() {
int n;
while(1) {
if(!waitline.empty()) {
n = waitline.remove(0);
mutex[n].acquire();
portions[n] += M;
cond_point[n].signal();
mutex[n].release();
}
}
}
所以我们想知道当wait()
语句阻塞point(int n)
信号时会发生什么。在我们的纪录片中,它说它们以原子方式释放互斥锁,因此没有干扰。但是其他代码行怎么样? (在point(int n)
函数中)? portions[n]
- 等 - 行被丢弃了吗? signal()
语句是否会以point(int n)
函数重新调用,但是以重置方式调用,以便函数以新的形式运行?
提前致谢!
答案 0 :(得分:1)
spring.redis.pool.max-active
spring.redis.pool.max-idle
spring.redis.pool.max-wait
spring.redis.pool.min-idle
的手册页提供了有关该行为的更多信息。它具体讨论了pthread的实现,但这适用于一般的每个实现
https://linux.die.net/man/3/pthread_cond_wait
最重要的部分是:
pthread_cond_wait()函数应阻塞条件变量
wait()
是一个阻止通话。线程由调度程序进入休眠状态。收到信号后,wait()
将返回。没有跳跃。执行将在wait()
之后继续执行。
注意:由于虚假唤醒,wait()
可能会在没有充分理由的情况下返回。因此,您应该检查是否真的符合条件。在循环中调用wait()
:
wait()
它们应该被调用线程锁定的互斥锁或未定义的行为结果调用。
调用// Condition: portions[n] > 0
while(portions[n] == 0)
cond_point[n].wait(mutex[n]);
时,需要锁定互斥锁。
成功返回后,互斥锁应被锁定,并由调用线程拥有。
当wait()
返回时,它将重新获得锁定。正如你所看到的,任何其他事情都没有意义,并且会导致令人困惑的情况。
所以这将是(可能)发生的事情:
wait()
顺便说一下:您应该使用另一个互斥锁将frycheff的调用同步到--- point ------------------------- frycheff -------------------
mutex[n].acquire(); Serving other Points
else if(portios[n] == 2) Serving other Points
waitline.add(n); Serving other Points
portions[n]--; Serving other Points
mutex[n].release(); Serving other Points
...
mutex[n].acquire(); (BLOCKS) if(!waitline.empty())
mutex[n].acquire(); n = waitline.remove(0);
if(portions[n] == 0) mutex[n].acquire(); (BLOCKS)
cond_point[n].wait(mutex[n]); mutex[n].acquire();
Sleeping portions[n] += M;
Sleeping cond_point[n].signal();
wait() reaquires mutex[n] mutex[n].release();
portions[n]--; if(!waitline.empty())
mutex[n].release(); if(!waitline.empty())
和if(!waitline.empty())
,因为ArrayList上的写操作不是threadsave。