Multithreading 使用监视器的单车道桥梁

Multithreading 使用监视器的单车道桥梁,multithreading,concurrency,parallel-processing,monitor,Multithreading,Concurrency,Parallel Processing,Monitor,在大学里,我从“Gregory R.Andrews多线程……编程基础”中得到了一个规范的并行编程问题(尽管我有一本更新的俄文版的书,但我找到了一个旧的英文变体,并试图正确地表达一切) 我还被指派去解决那个任务,导师让我从“读者-作者”任务中模仿读者的行为 单车道桥。来自北方和南方的汽车到达一个单车道桥 车道桥。朝同一方向行驶的汽车可以在同一方向通过大桥 时间到了,但朝相反方向行驶的汽车不能。 为这个问题制定一个解决方案。将汽车建模为流程,并使用 监视同步。首先指定监视器不变量,然后开发 监视器的

在大学里,我从“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