由《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。但是想要通过博客把这个问题写出来,这个过程就会细想或者仔细看一下,
于是就会把问题解决了。
其实,很多时候,写这些东西只是为了让自己能够更仔细、更清楚的了解问题所在。有事看书也懂了书中所讲的,但是面试的时候或者工作中解决问题还是不能够灵活应对,主要还是理解不够透彻。通过写博客,既能够训练自己把问题讲清楚,以便以后面试的时候能够应到入流,同时,也能加深自己的理解,工作中遇到问题能够下意识的考虑使用这些知识,这才算学以致用。
由《win32多线程程序设计》临界区的问题所想的更多相关文章
- 深入浅出Win32多线程程序设计之基本概念
一.深入浅出Win32多线程程序设计之基本概念[转] 引言 从单进程单线程到多进程多线程是操作系统发展的一种必然趋势,当年的DOS系统属于单任务操作系统,最优秀的程序员也只能通过驻留内存的方式实现所谓 ...
- win32多线程程序设计笔记(第二章)
第二章线程的第一次接触,主要讲了如何创建线程以及需要注意的几点. 一.创建线程 与调用函数的过程类似;线程只不过用CreateThread的API将函数封装起来,并产生一个与主程序同时执行的程序来调用 ...
- win32多线程程序设计笔记(第四章下)
上一笔记讲了同步机制中的临界区域(Critical Sections).互斥器(Mutexes),下面介绍同步机制中的另外两种. 信号量(Semaphores) 举个例子: 现在有人要租车,接待他的代 ...
- win32多线程程序设计笔记(第五章)
前面章节介绍了线程创建等过程,现在的问题是:如何在某个线程内终止另外一个正在运行的线程? windows核心编程中提到终止运行线程的方法: 1)线程函数自己返回: 2)线程通过调用ExitThread ...
- win32多线程程序设计
标题是一本书名,写得挺有意思的,是今天早上同事带过来的,我借过来看了一会儿. 然后按照书里面前面几章的内容敲了一些代码,跑了几个例子看了一下. 创建线程的函数: HANDLE CreateThread ...
- 多线程学习:win32多线程编程基本概念(转)
一.定义: 1.进程和线程的区别 进程:是程序的执行过程,具有动态性,即运行的程序就叫进程,不运行就叫程序 ,每个进程包含一到多个线程.线程:系统中的最小执行单元,同一进程中有多个线程,线程可以共享资 ...
- Win32多线程编程(1) — 基础概念篇
内核对象的基本概念 Windows系统是非开源的,它提供给我们的接口是用户模式的,即User-Mode API.当我们调用某个API时,需要从用户模式切换到内核模式的I/O System Serv ...
- win32多线程-重写消息循环
最近正在学习<win32多线程程序设计>,这是其中一段重写消息循环的代码事例,以后可能用的上. while (!quit || gNumPrinting > 0) { // Wait ...
- win32多线程编程
关于多线程多进程的学习,有没有好的书籍我接触的书里头关于多线程多进程部分,一是<操作系统原理>里面讲的相关概念 一个是<linux基础教程>里面讲的很简单的多线程多进程编程 ...
随机推荐
- 使用oracle写if判断
DECLARE L_X INT; BEGIN SELECT COUNT(*) INTO L_X FROM SYSTEMROLEFUNCTION WHERE ROLEID = '1'; IF L_X & ...
- 检索COM类工厂中CLSID为{000209FF-0000-0000-C000-000000000046}的组件时失败,原因是出现以下错误: 80070005
检索COM类工厂中CLSID为{000209FF-0000-0000-C000-000000000046}的组件时失败,原因是出现以下错误: 80070005 http://blog.csdn.net ...
- Activity和Service的生命周期(图)
1.Activity的生命周期 情形一.一个单独的Activity的正常的生命过程是这样的:onCreate->onStart->onPause->onStop->onDest ...
- js动画 无缝轮播 进度条 文字页面展示 div弹窗遮罩效果
1.无缝轮播 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.a ...
- webserer错误
HTTP 错误 404.17 - Not Found 请求的内容似乎是脚本,因而将无法由静态文件处理程序来处理. 解决方法: C:\Program Files\Microsoft Visual Stu ...
- 把int放在一个char数组里(用于处理每一位数字)
sprintf(): #include <stdio.h> void put_int_with_space(int v) { char str[50]; //定义一个足够大的 ...
- CodeForces 670D2 Magic Powder 二分
D2. Magic Powder - 2 The term of this problem is the same as the previous one, the only exception — ...
- C#语法基础用法Dictionary排序
Dictionary排序 1.先看效果图: 2.核心逻辑如下: Dictionary<int, string> list = new Dictionary<int, string&g ...
- C#变量与数据类型
数据类型: 整型:int short long byte 小数:double float decimal 布尔:bool 字符:char 定义变量: 数据类型 变量名 [= 值]; 变量名的命名规则: ...
- UI事件 计算器界面
1.MainActivity.java package com.example.administrator.testapp2; import android.support.v7.app.AppCom ...