我理解正常一个进程的程序是这样写的:
int number;
enter_region(number);
这里是临界区的操作;
leave_region();
当进程 0 执行了 enter_region(0);,但还没有执行 leave_region 时。此时进程 1 去执行 enter_region(1);,会发现:
turn == process
成立了(我理解,这代表当前进程正在请求)但是现在有这种特殊情况:
turn == process&&interested[other] == True
的第一个条件,直接短路,然后不执行这个循环,然后进程 0 进入到 临界区。turn == process
不成立,就直接短路,然后就让当前进程去临界区了呢(虽然确实是正常工作了,这之后,进程 0 进入临界区,进程 1 则无限循环了)?总感觉有点反直觉,不知道该怎么解释turn == process
成立,但interested[other] == True
不成立。 1
churchmice 2022-04-10 01:18:42 +08:00 via Android
不会啊,进程 0 做完之后对于进程 1 的 while 条件 interested[other] 就不成立了,进程 1 就会跳出 while 去 critical region 了
|
2
amiwrong123 OP @churchmice #1
是的,确实如你所说,能够正常工作的。 我的纠结点在于: - 我觉得应该既要判断 turn 的值,也要判断 interested 数组的值。两个都判断完事之后,才可以去临界区。 - 但是我帖子里这种特殊情况的话,进程 1 只判断 turn == process ,后面那个条件就直接短路了(它就根本没判断 interested 数组) 但是,后来我一想。既然执行到 turn == process ,说明 interested 数组的自己索引位置已经变成 True 。然后 turn == process 不成立,说明另一个进程也至少执行到了 trun = process 这句,那么另一个进程肯定会进入无限循环,所以 这里可以短路判断。 |
3
heiher 2022-04-10 15:28:57 +08:00 via Android
刚执行过 turn = self_process ,随后的判断 turn == self_process 就不成立,则说明一定有其它进程也执行了 turn = process ,但也一定会卡在 interested[other] == true 条件上,所以当前线程可以安全进入临界区。另外,挺有意思的是这个算法在 x86 的内存模型上需要使用内存屏障指令。
|
4
amiwrong123 OP @heiher #3
应该在哪里加 内存屏障阿,另外,应该加什么内存屏障阿 |
5
heiher 2022-04-10 17:47:27 +08:00 via Android
@amiwrong123 需要防止 Store interested[process] 乱序到 Load turn 之后:
interested[process] = TRUE; turn = process; storeload_barrier (mfence on x86) while (turn == process && interested[other] == TRUE); |