• 由《win32多线程程序设计》临界区的问题所想


    之前看侯捷翻译的《win32多线程程序设计》中关于线程同步中的临界区问题,其中举得例子是对链表的操作。死锁的问题是对一个Swaplist函数的问题,现列举代码如下:

    void SwapLists(List *list, List *list2)
    {
      List *tmp_list;
      EnterCriticalSection(list1->critical_sec);
      EnterCriticalSection(list2->critical_sec);
      tmp->list = list1->head;
      list1->head = list2->head;
      list2->head = temp->list;
      LeaveCriticalSection(list1->critical_sec);
      LeaveCriticalSection(list2->critical_sec);
    }

    书中阐述如下:假设下面两次调用发生在不同线程的同一个时间点:
    线程A SwapLists(home_address_list, work_address_list);
    线程B SwapLists(work_address_list, home_address_list);

    而在线程A的 SwapLists() 的第一次 EnterCriticalSection() 之后,发生了
    context switch(译注:也就是调度程序选换了一个线程),然后线程B执行

    了它的 SwapLists()操作,两个线程于是会落入“我等你,你等我”的轮回。

    一直有一个问题问题:

    假设线程A执行到第一次EnterCriticalSection()后,切换到了线程B。那么线程B走到第一次调用EnterCriticalSection(),由于线程A已经获得list1的临界区,

    线程B走到list1就会等待。

          但仔细一看才知道,线程A和线程B的list1和list2都是参数,在两个线程调用swaplist时可以相反的传入连个参数。

          也正如例子所示:

               线程A的参数调用顺序是:home_address_list, work_address_list

               线程B的参数调用顺序是:work_address_list、home_address_list。

               所以线程A进入home_address_list的临界区,然后切换到线程B进入到work_address_list的临界区。这样就形成死锁了。

          由于看书不细心,或者知道到函数那一部分代码,很容易就只看到局部变量list1和list2。但是想要通过博客把这个问题写出来,这个过程就会细想或者仔细看一下,

    于是就会把问题解决了。

         其实,很多时候,写这些东西只是为了让自己能够更仔细、更清楚的了解问题所在。有事看书也懂了书中所讲的,但是面试的时候或者工作中解决问题还是不能够灵活应对,主要还是理解不够透彻。通过写博客,既能够训练自己把问题讲清楚,以便以后面试的时候能够应到入流,同时,也能加深自己的理解,工作中遇到问题能够下意识的考虑使用这些知识,这才算学以致用。

  • 相关阅读:
    iTerm2 颜色配置
    IOS_问题: Xcode8 安装KSImageName插件, 编代码就崩了
    IOS_设置启动图片若干问题
    Android 多国语言
    Reveal 配置与使用
    自定义代码块
    Android 动画
    SQL
    dialog
    2016-1-18UIlabel学习,正则表达式
  • 原文地址:https://www.cnblogs.com/criticalsection/p/4096107.html
Copyright © 2020-2023  润新知