Multithreading 使用监视器的单车道桥梁
在大学里,我从“Gregory R.Andrews多线程……编程基础”中得到了一个规范的并行编程问题(尽管我有一本更新的俄文版的书,但我找到了一个旧的英文变体,并试图正确地表达一切)Multithreading 使用监视器的单车道桥梁,multithreading,concurrency,parallel-processing,monitor,Multithreading,Concurrency,Parallel Processing,Monitor,在大学里,我从“Gregory R.Andrews多线程……编程基础”中得到了一个规范的并行编程问题(尽管我有一本更新的俄文版的书,但我找到了一个旧的英文变体,并试图正确地表达一切) 我还被指派去解决那个任务,导师让我从“读者-作者”任务中模仿读者的行为 单车道桥。来自北方和南方的汽车到达一个单车道桥 车道桥。朝同一方向行驶的汽车可以在同一方向通过大桥 时间到了,但朝相反方向行驶的汽车不能。 为这个问题制定一个解决方案。将汽车建模为流程,并使用 监视同步。首先指定监视器不变量,然后开发 监视器的
我还被指派去解决那个任务,导师让我从“读者-作者”任务中模仿读者的行为
单车道桥。来自北方和南方的汽车到达一个单车道桥 车道桥。朝同一方向行驶的汽车可以在同一方向通过大桥 时间到了,但朝相反方向行驶的汽车不能。 为这个问题制定一个解决方案。将汽车建模为流程,并使用 监视同步。首先指定监视器不变量,然后开发 监视器的主体。确保公平。(让汽车带着tums)
我在谷歌上搜索并找到了类似任务的解决方案(),但讲师说大部分都是无用的和不正确的,我最终得到了以下解决方案:
monitor onelanebridge{
int nb=0,sb=0; //Invar:(nb==0 and sb<=1)or(sb=0 and nb<=1)
cond nbfreetogo,sbfreetogo; //conditional variables
procedure enter_n(){
if(sb!=0andnb==0) wait(nbfreetogo);
nb++;
}
procedure enter_s(){
if(nb!=0andsb==0) wait(sbfreetogo);
sb++;
}
procedure leave_n(){
nb--;
if(nb==0) signal(sbfreetogo);
}
procedure leave_s(){
sb--;
if(sb==0) signal(nbfreetogo);
}
}
所以我应该用其中的一些解决这个问题。你的监视器onelanebridge离目标不远,但它没有公平的概念。如果有稳定的北行交通流,没有什么会触发转向南行。您需要将等待计数和“活动”计数分开 一个简单的公平方法是交替,因此您可以将“活动”计数器限制为1;并检查它变为零时是否切换。 为避免煽动道路愤怒,您可以根据单线路段的通行时间选择限制 现在,车辆将在方向正确的enter_uns中等待,但由于限制,必须等待,因此您的if(cond)等待需要变成while(更复杂的cond)等待 并发编程是不自然的,但通过实践可以变得根深蒂固。试着想想眼前的问题,而不是我如何运用这些机制
monitor RW_Controller {
int nr = 0, nw =0; //Invar: (nr == 0 or nw == 0) and nw <= 1
cond oktoread; # recieves signal, when nw == 0
cond oktowrite; # recieves signal, when nr == 0 и nw == 0
procedure request_read() {
while (nw > 0) wait(oktoread);
nr = nr + 1;
}
procedure release_read() {
nr = nr - 1;
if (nr == 0) signal(oktowrite);
# run one writer-process
}
procedure request_write() {
while (nr > 0 || nw > 0) wait(oktowrite);
nw = nw + 1 ;
}
procedure release_ write() {
nw = nw - 1;
signal(oktowrite); # run one writer-process and
signal_all(oktoread); # all reader-processes
}
}
wait(cv)//wait at end of queue
wait(cv,rank)//wait in order of increasing value of rank
signal(cv)//awaken process at end of queue then continue
signal_all(cv)//awaken all processes at end of queue then continue
empty(cv) //true if wait queue is empty; false otherwise
minrank(cv) //value of rank of process at front of wait queue