windows线程同步
一、前言
之前在项目中,由于需要使用到多线程,多线程能够提高执行的效率,同时也带来线程同步的问题,故特此总结如下。
二、windows线程同步机制
windows线程同步机制常用的有几种:Event、Critical Section、Mutex、Semaphore。
1.Critical Section(临界区)
适用范围: 单一进程的各线程之间用来排它性占有
特性: 不是内核对象,是这里提到的四种机制中速度效率最高的(注意:由于临界区是非内核对象,可在用户空间维护,则无句柄,那么就不能使用WaitForMultipleObjects防止死锁的问题了)。无法监测是否被线程放弃。如果在Critical Sections中间突然程序crash或是exit而没有调用LeaveCriticalSection,则结果是该线程所对应的内核不能被释放,该线程成为死线程。
临界区相关函数:
VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); //函数功能初始化一个临界资源对象。
VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); // 进入临界区
VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection); // 离开临界区
VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection); // 销毁临界区
2.Mutex(互斥内核对象)
适用范围: 不同线程之间用来排它性占有
特性: 核心对象,有句柄,有拥有者,哪个线程拥有mutex,就占有mutex的所有权,非拥有者执行ReleaseMutex会出错。mutex可以跨进程同步。
互斥量相关函数:
a.创建
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, //安全属性结构指针
BOOL bInitialOwner, //是否占有该互斥量
LPCTSTR lpName //设置互斥对象的名字
);
b.打开一个现有命名互斥量
HANDLE OpenMutex(
DWORDdwDesiredAccess, // access
BOOLbInheritHandle, // inheritance option
LPCTSTRlpName // object name
);
c.占有/获取互斥量
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
d.释放互斥量
BOOL WIANPI ReleaseMutex(
HANDLE hMutex
);
3.Event(事件内核对象)
适用范围: 用来控制对象信号的接收,常与信号系统结合起来
特性: 核心对象,有句柄,有两种不同类型的事件对象。一种是人工重置的事件,另一种是自动重置的事件。当人工重置的事件得到通知时(signaled),等待该事件的所有线程均变为可调度线程,直到调用ResetEvent,事件才会变为unsignaled。当一个自动重置的事件得到通知时,等待该事件的线程中只有一个线程变为可调度线程,事件则自动变为unsigned。
SetEvent后,自动置位事件则会保持状态,直到有等待事件的,之后自动复位。手动复位事件,则保存signaled状态直到调用ResetEvent。
PulseEvent后,对于手动复位事件,所有当前线程(如果有的话)会得到释放,而后事件会被复位为unsigned。(不建议使用)
WaitForMultipleObjects,只有当所有等待的事件同时处于signaled,才会释放,对于自动复位的事件在线程释放后自动复位。
相关函数:CreateEvent, OpenEvent,SetEvent, ResetEvent, PulseEvent。
4.Semaphore(信号内核对象)
适用范围: 用来限制资源占用
特性: 核心对象,没有拥有者,任何线程都可释放。信号量(Semaphore)内核对象对线程的同步方式与前面几种方法不同,它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。在用 CreateSemaphore()创建信号量时即要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。但是当前可用计数减小到0时则说明当前占用资源的线程数已经达到了所允许的最大数目,不能在允许其他线程的进入,此时的信号量信号将无法发出。线程在处理完共享资源后,应在离开的同时通过 ReleaseSemaphore()函数将当前可用资源计数加1。在任何时候当前可用资源计数决不可能大于最大资源计数。
函数: CreateSemaphore OpenSemaphore ReleaseSemaphore
三、对比
Mutex与Critical Section对比
1.Mutex如果被终止线程所泛起,会是已传信的,其他线程不会永远阻塞;而Critical Section则不是,如果被终止线程没有释放,那么其他等待线程将永远阻塞。
2.Mutex是内核对象,,有超时机制(有句柄,可以是使用WaitFor_函数实现);而CS非内核对象,无句柄,不能使用WaitFor系列函数,实现超时机制,只能使用TryEnterCriticalSection轮询。
3.Mutex可命名,可以跨进程同步,CS不行。
4.Mutex可在创建时,立即指定对该mutex的拥有权,CS没有不行。
5.CS由于是非内核对象,不需要频繁的切换程序运行的状态到核心态下,所有CS几乎总是比Mutex要快。
非内核对象(CS)与内核对象(其他的)对比:
1.内核对象有句柄能使用WaitForMultipleObjects,一次等待多个对象,避免死锁;
2.CS无句柄,不能使用,需要自己考虑防止死锁的问题。(给CS编号,按照一定顺序获取,打破形成环)。
3.对于上面几种命名的内核同步对象,可以进行跨进程同步;而,CS是非内核对象,直接建构在用户空间下,速度快的同时带来另一个问题,那就是没有办法跨进程同步。
四、后记
对于CS的使用,我们一般使用内部类的形式,防止异常的时候没有LeaveCriticalSection。
这个可能总结不够全,希望以后能够进行总结。另外该博文参考了http://www.cnblogs.com/luxiaoxun/archive/2012/10/10/2717765.html
windows线程同步的更多相关文章
- windows线程同步的总结
一 线程 1)如果你正在编写C/C++代码,决不应该调用CreateThread.相反,应该使用VisualC++运行期库函数_beginthreadex,退出也应该使用_endthreadex.如果 ...
- 关于windows线程同步的四种方法
#include "stdafx.h" #include "iostream" #include "list" #include " ...
- Windows线程同步(下)
线程同步三:事件 CreateEvent:Creates or opens a named or unnamed event object. HANDLE WINAPI CreateEvent( _I ...
- Windows线程同步(上)
先介绍一个创建线程的API,参考:https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx ...
- windows线程同步的几种方式
以下为main函数的测试代码 具体线程同步的实现代码请下载:https://github.com/kingsunc/ThreadSynchro #include <stdio.h> #in ...
- windows 线程同步
Windows 临界区,内核事件,互斥量,信号量. 临界区,内核事件,互斥量,信号量,都能完成线程的同步,在这里把他们各自的函数调用,结构定义,以及适用情况做一个总结. 临界区: 适用范围:它只能同步 ...
- 总结windows多线程同步互斥
windows多线程同步互斥--总结 我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同 ...
- Windows线程+进程通信
一 Windows线程进程 1)定义 按照MS的定义, Windows中的进程简单地说就是一个内存中的可执行程序, 提供程序运行的各种资源. 进程拥有虚拟的地址空间, 可执行代码, 数据, 对象句柄集 ...
- 操作系统中的进程同步与Window中利用内核对象进行线程同步的关系
操作系统中为了解决进程间同步问题提出了用信号量机制,信号量可分为四种类型分别是互斥型信号量,记录型信号量,AND型信号量,信号量集. 互斥型信号量 互斥型信号量是资源数量为1的特殊的记录型信号量.表示 ...
随机推荐
- 【BZOJ 1026】 [SCOI2009]windy数
Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? In ...
- Notes of the scrum meeting(11/1)
meeting time:9:00~10:30p.m.,November 1st,2013 meeting place:20号公寓楼前 attendees: 顾育豪 ...
- 历时一周,unity3d+xtion打造我的第一个休闲体感小游戏《空降奇兵》
1.游戏介绍 本游戏属于休闲小游戏,主要操作如下: 菜单控制:举起左手或右手,点击左边或者右边的菜单:挥动左手或右手,选择关卡: 操作方式:玩家跳跃,游戏中的伞兵从飞机开始降落:玩家通过控制伞兵的左右 ...
- 在唯一密钥属性“value”设置为“Default.aspx”时,无法添加类型为“add”的重复集合项
环境:windows server 2012 asp.net 找到网站目录:wwwroot ,打开web.config文件,在 在<files>与</files>之间加入代码 ...
- [book]awesome-machine-learning books
https://github.com/josephmisiti/awesome-machine-learning/blob/master/books.md Machine-Learning / Dat ...
- 处理一则MySQL Slave环境出现ERROR 1201 (HY000): Could not initialize master info structure的案例
mysql> start slave; ERROR (HY000): Slave failed to initialize relay log info structure from the r ...
- IntelliJ IDEA 15 设置默认浏览器
一.设置系统默认浏览器 二.设置项目启动默认浏览器
- Leetcode#78 Subsets
原题地址 有两种方法: 1. 对于序列S,其子集可以对应为一个二进制数,每一位对应集合中的某个数字,0代表不选,1代表选,比如S={1,2,3},则子集合就是3bit的所有二进制数. 所以,照着二进制 ...
- 关于ios中的文本操作-简介
来源:About Text Handling in iOS 官方文档 iOS平台为我们提供了许多在app中展示文本和让用户编辑文本的方式.同时,它也允许你在app视图中展示格式化的文本和网页内容.你可 ...
- c#操作剪切板
C#定义了一个类System.Windows.Forms.Clipboard来简化剪切板操作,这个类有一个静态方法,主要有: Clear 清除剪切板中的所有数据: ContainsData,Conta ...