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的特殊的记录型信号量.表示 ...
随机推荐
- JAVA equals, ==
都是判相等,对于基本变量没区别,只是对动态变量(即对象)有区别: ==:引用相等(reference comparison).对于对象引用,即判断引用值也就是地址是否相等.即如果Object a,b, ...
- iOS常见问题(2)
一.模拟器黑屏 解决方法: 二.打代码时,Xcode没提示 解决方法: 0. 点击Preferences 1. 进入Text Editing 2. 勾选 三.有时候可能在勾选 Autolayout的时 ...
- sharepoint 认证
MCPD http://www.microsoft.com/learning/en/us/mcpd-certification.aspx#fbid=YktyKIYXeFg Exam 70-573: T ...
- Week2 Team Homework: 必应输入法的软件分析和用户需求调查
一.选题和目标人群的确定 4月8日,微软宣布推出首款整合搜索的中文云输入法“必应Bing输入法”,其前身是“英库拼音输入法”.微软宣称,该输入法界面干净,无广告.无插件,即使是在性能相对不高的电脑上, ...
- php多条件查询
$sql)"; if(!empty($uid)) { $sql .=" and uid= ".$uid; } if(!empty($time1) && e ...
- ios 框架学习笔记
ios主要的系统层次: 一.Cocoa Touch 层:创建应用程序主要使用的框架. 1.关键技术: AirDrop:实现应用间通信. Text Kit:处理文本和排版. UIKit Dynamics ...
- error X3025:global variables are implicitly constant, enable compatibility mode to allow modification
global variables are implicitly constant, enable compatibility mode to allow modification http://xbo ...
- failed creating the Direct3d device--debug
D3DDEVTYPE_REF 使用REF设备,用软件模拟Direct3D API 照理说是为了让电脑能跑本机不能硬件执行的渲染命令的 但我 pDeviceSettings->d3d9.Devic ...
- [设计模式] 7 适配器模式 adapter
在 Adapter 模式的结构图中可以看到,类模式的 Adapter 采用继承的方式复用 Adaptee的接口,而在对象模式的 Adapter 中我们则采用组合的方式实现 Adaptee 的复用 类模 ...
- Volatile 说明
Java™ 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了实现代码线程的安全性.其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低) ...