c - 试图理解彼得森的算法

标签 c multithreading algorithm concurrency process

我试图理解 Peterson 的算法,我遇到了这个问题。我追踪代码并写下我的观察结果。请检查我的观察,我走在正确的轨道上吗?

教科书中的

问题:假设只有两个进程,一个pid值为0,另一个pid value 1. 这个并发算法有什么问题?

  while(True)
    {
     flag[pid] = 1
     turn = 1-pid
     while( flag[1-pid] && turn == 1-pid ); // busy wait

     // critical section
     ...
     // end of critical section

     flag[pid] = 0
    }

跟踪代码:

    ---------- Process 0: ---------- | ---------- Process 1: ----------
                                     |
    pid = 0                          |    pid = 1
    flag[0] = 1                      |    flag[1] = 1
    turn = 1 - 0 = 1                 |    turn = 1 - 1 = 0
                                     |
    while (flag[1 - 0]               |    while (flag[1 - 1]    
            && turn == (1 - 0))      |            && turn == (1 - 1))
                                     |
    // --> while (flag [1] && true)  |    // --> while (flag [0] && true)
    // --> while (flag [1])          |    // --> while (flag [0])

我的观察

  1. 我认为在繁忙的等待部分,两个 while 循环都可能运行 永远。
  2. 我还认为当其中一个进程例如进程 0 退出时 它的 while 循环然后它可以将它的标志设置为 false (flag[0] = 0) 并导致 其他进程不要运行。因此,进程 0 可以运行两次,而进程 1 根本不运行。此外,它还会导致进程 1 饿死,反之亦然。

最佳答案

Peterson 算法 保证在没有任何饥饿的情况下访问两个进程的关键部分。

  • flag表示希望进入临界区
  • turn 被一个进程用来让另一个进程完成等待并继续到临界区
  • 当一个进程完成它在临界区 的工作时,它表明它的愿望已经消失 (flag[pid] = False)。这允许另一个人进入该部分。但是,如果一个进程由于上下文切换而打开和关闭它的 flag 而另一个进程没有注意到它,它仍然必须切换它的 turn 标志。

总结

Peterson 算法之所以有效,是因为每个过程都有以下思维方式:

我想访问临界区。那么,轮到我了


所以你看,最后一切都很好。没有饥饿,每个进程都在没有卡住,并且临界区被两个进程反复访问再来一遍。

关于c - 试图理解彼得森的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26693414/

相关文章:

algorithm - Left Child Right Sibling 二叉树中的平均叶高

c - 如何找到 while 循环的时间复杂度(Big O)?

客户端-服务器回显聊天(多路 I/O + 线程)

将 unsigned int 转换为 int 指针 段错误

mysql - 使用mysql查询获取一个月中星期日的所有日子?

ios - 将单独线程检索的数据返回到主线程以在 UI 中显示

algorithm - 对 [0,2k] 之间的一系列 n 个数字进行排序,每对之间存在 : |Ai-Aj|>=k/n

iphone - 计算最佳运输容器空间分配

c - 我如何在我的源文件中调用一个函数,其中仅包含 c 中的头文件?

c - 当程序使用自定义入口点(使用 gcc 7.4.0)运行时,scanf 会产生段错误