之前看侯捷翻译的《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。但是想要通过博客把这个问题写出来,这个过程就会细想或者仔细看一下,

于是就会把问题解决了。

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

由《win32多线程程序设计》临界区的问题所想的更多相关文章

  1. 深入浅出Win32多线程程序设计之基本概念

    一.深入浅出Win32多线程程序设计之基本概念[转] 引言 从单进程单线程到多进程多线程是操作系统发展的一种必然趋势,当年的DOS系统属于单任务操作系统,最优秀的程序员也只能通过驻留内存的方式实现所谓 ...

  2. win32多线程程序设计笔记(第二章)

    第二章线程的第一次接触,主要讲了如何创建线程以及需要注意的几点. 一.创建线程 与调用函数的过程类似;线程只不过用CreateThread的API将函数封装起来,并产生一个与主程序同时执行的程序来调用 ...

  3. win32多线程程序设计笔记(第四章下)

    上一笔记讲了同步机制中的临界区域(Critical Sections).互斥器(Mutexes),下面介绍同步机制中的另外两种. 信号量(Semaphores) 举个例子: 现在有人要租车,接待他的代 ...

  4. win32多线程程序设计笔记(第五章)

    前面章节介绍了线程创建等过程,现在的问题是:如何在某个线程内终止另外一个正在运行的线程? windows核心编程中提到终止运行线程的方法: 1)线程函数自己返回: 2)线程通过调用ExitThread ...

  5. win32多线程程序设计

    标题是一本书名,写得挺有意思的,是今天早上同事带过来的,我借过来看了一会儿. 然后按照书里面前面几章的内容敲了一些代码,跑了几个例子看了一下. 创建线程的函数: HANDLE CreateThread ...

  6. 多线程学习:win32多线程编程基本概念(转)

    一.定义: 1.进程和线程的区别 进程:是程序的执行过程,具有动态性,即运行的程序就叫进程,不运行就叫程序 ,每个进程包含一到多个线程.线程:系统中的最小执行单元,同一进程中有多个线程,线程可以共享资 ...

  7. Win32多线程编程(1) — 基础概念篇

      内核对象的基本概念 Windows系统是非开源的,它提供给我们的接口是用户模式的,即User-Mode API.当我们调用某个API时,需要从用户模式切换到内核模式的I/O System Serv ...

  8. win32多线程-重写消息循环

    最近正在学习<win32多线程程序设计>,这是其中一段重写消息循环的代码事例,以后可能用的上. while (!quit || gNumPrinting > 0) { // Wait ...

  9. win32多线程编程

    关于多线程多进程的学习,有没有好的书籍我接触的书里头关于多线程多进程部分,一是<操作系统原理>里面讲的相关概念   一个是<linux基础教程>里面讲的很简单的多线程多进程编程 ...

随机推荐

  1. ural 1112,LIS

    题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1112 题意:n根线段,要拿走一些,使得任何的线段的左段没有在某一个线段的内部. 其实说白 ...

  2. ExecutorService线程池讲解

    ExecutorService 建立多线程的步骤: 1.定义线程类 class Handler implements Runnable{ } 2.建立ExecutorService线程池 Execut ...

  3. Java的Properties类和读取.properties文件

    一..properties文件的作用 Properties属性文件在JAVA应用程序中是经常可以看得见的,也是特别重要的一类文件.它用来配置应用程序的一些信息,不过这些信息一般都是比较少的数据,没有必 ...

  4. AJAX文档

    AJAX 文档 AJAX开发简略.................................................................................... ...

  5. Android BroadcastReceiver广播接受者

    静态注册 配置清单表注册:只要曾经注册过哪怕关闭也能调用  方式一:sendBroadCastReceive   广播的步骤:       发送  无序广播,普通广播       (1).发送方    ...

  6. .NetDOM操作--un

    DOM操作操作相关元素:里:children(),find("选择器")外:parent(),parents("选择器")下:next(),nextAll(选择 ...

  7. Cheatsheet: 2013 08.20 ~ 08.31

    .NET Protobuf-net: the unofficial manual 5 Common C# Misconceptions What is new in the Mono project ...

  8. Devexpress TreeList选择父级联动

    Treelist当显示复选框后,父级和子级的复选框没有关联,使用过程中很不便,如图所示 自己给treelist添加父子级联动 /// <summary> /// 初始化TreeList,父 ...

  9. Limiting To Select Only 5 Check Boxes Out Of Ten In Oracle Forms

    Suppose you want to give an option to user to select only 5 check boxes from given any number of che ...

  10. sql注入在线检测(sqlmapapi)

    版权:http://blog.csdn.net/yueguanghaidao/article/details/38026431 每次看都不方便   摘抄下来 之前一搞渗透的同事问我,sqlmapapi ...