Windows提高_2.3第三部分:内核区同步
第三部分:内核区同步
等待函数(WaitForObject)
等待函数的形式
单个:WaitForSingleObject
多个:WaitForMultipleObjects
一个可以被等待的对象通常由两种状态,分别是:
可等待(激发态)(有信号):等待函数【不会阻塞】
不可等待(非激发态)(无信号):等待函数需要等待一定时长并【阻塞】
等待函数的副作用:
改变被等待对象的信号状态
- #include <iostream>
- #include <windows.h>
-
- // 工作线程
- DWORD WINAPI WorkerThread(LPVOID lpThreadParameter)
- {
- // 输出 0 ~ 99
- for (int i = ; i < ; ++i)
- {
- printf("%d\n", i);
- }
-
- return ;
- }
-
- int main()
- {
- HANDLE Threads[] = { };
-
- // 创建两个线程
- Threads[] = CreateThread(NULL, NULL, WorkerThread, NULL, NULL, NULL);
- Threads[] = CreateThread(NULL, NULL, WorkerThread, NULL, NULL, NULL);
- Threads[] = CreateThread(NULL, NULL, WorkerThread, NULL, NULL, NULL);
-
- // 函数返回的两种情况
- // 1. 被等待对象处于有信号状态
- // 2. 等到超时函数会返回,但是等待失败
-
- // 等待两个线程退出
- // 1. 一个可以被等待的内核对象
- // 2. 等待时长,如果是-1 表示一直等待
- // WaitForSingleObject(ThreadHandles[0], INFINITE);
- // WaitForSingleObject(ThreadHandles[1], INFINITE);
-
- // 等待多个内核对象
- // 1. 需要等待多少个内核对象
- // 2. 内核对象句柄的数组
- // 3. 是否等待所有内核对象编程变成有信号的
- // 4. 等待的时长,单位是毫秒
- // WaitForMultipleObjects(2, ThreadHandles, TRUE, INFINITE);
-
- // 有任何一个执行完毕,另外一个就不执行了
- WaitForMultipleObjects(, Threads, FALSE, INFINITE);
-
- // 等待函数的副作用:修改被等待对象的信号状态
-
- return ;
- }
互斥体(Mutex)
特点:拥有临界区的线程拥有者概念,但是线程崩溃不会死锁,执行较慢
函数
创建:CreateMutex,如果第二个参数是FALSE,那么就是可等待
打开:OpenMutex
保护:WaitForSingleObject: 把互斥体置为不可等待
释放:ReleaseMutex把互斥体置为可等待
关闭:CloseHandle
- // 1. 创建一个互斥体内核对象
- // - 安全属性,初始状态,名称
- HANDLE Mutex = CreateMutex(NULL, FALSE, L"Mutex");
-
- DWORD WINAPI ThreadPro1(LPVOID lpThreadParameter)
- {
- // 为 g_Number 自增 100000 次
- for (int i = ; i < ; i++)
- {
- // 2. 使用等待函数对互斥体进行等待,当互斥体处于激发态就会等待成功
- // 当等待成功时,会将互斥体置为无信号状态
- WaitForSingleObject(Mutex, INFINITE);
- g_Number++;
- // 3. 执行完代码之后需要恢复有信号状态
- ReleaseMutex(Mutex);
- }
- return ;
- }
事件(Event)
特点:可以手动选择是否产生副作用,如果设置为手动状态,那么就不产生副作用
函数:
创建:CreateEvent()
打开:OpenEvent()
保护:WaitForSingleObject()
设置为非激发态:ResetEvent()
退出(设置为激发态):SetEvent()
关闭:CloseHandle
- // 1. 创建一个事件内核对象
- // - 安全属性,是否自动,初始状态,名称
- HANDLE Event = CreateEvent(NULL, FALSE, TRUE, L"Event");
- // HANDLE Event = CreateEvent(NULL, TRUE, TRUE, L"Event");
-
- DWORD WINAPI ThreadPro1(LPVOID lpThreadParameter)
- {
- // 为 g_Number 自增 100000 次
- for (int i = ; i < ; i++)
- {
- // 注意:如果使用手动模式,等待函数就没有副作用
- // 可以使用 ResetEvent 手动设置信号状态,但是没有意义
- // 原因是 ResetEvent 本身不是一个原子操作
-
- // 2. 使用等待函数对事件进行等待,当事件处于激发态就会等待成功
- // 当等待成功时,会将事件置为无信号状态
- WaitForSingleObject(Event, INFINITE);
- g_Number++;
- // 3. 执行完代码之后需要恢复有信号状态
- SetEvent(Event);
- }
- return ;
- }
信号量
特点:有多把锁,可以控制活动线程的数量,没有线程拥有者概念。
如果锁的最大个数是1,则用法和互斥体类似
函数:
创建:CreateSemaphore
打开:OpenSemaphore
上锁:WaitForSingleObject
解锁:ReleaseSemaphore
关闭:CloseHandle
- // 1. 创建一个信号量内核对象
- // - 安全属性,当前信号,最大信号,名称
- HANDLE Semaphore = CreateSemaphore(NULL, , , L"Semaphore");
-
- DWORD WINAPI ThreadPro1(LPVOID lpThreadParameter)
- {
- // 为 g_Number 自增 100000 次
- for (int i = ; i < ; i++)
- {
- // 2. 使用等待函数对信号量进行等待,当信号个数>1表示可等待
- // 当等待成功时,会将信号个数 -1
- WaitForSingleObject(Semaphore, INFINITE);
- g_Number++;
- // 3. 执行完代码之后需要将信号个数 +1
- // 信号量对象,+几个信号,之前有多少个信号
- ReleaseSemaphore(Semaphore, , NULL);
- }
- return ;
- }
Windows提高_2.3第三部分:内核区同步的更多相关文章
- 《windows核心编程系列》三谈谈内核对象及句柄的本质
内核对象 本章讨论的是相对抽象的概念,不涉及任何具体的内核对象的细节而是讨论所有内核对象的共有特性. 首先让我们来了解一下什么是内核对象.内核对象通过API来创建,每个内核对象是一个数据结构,它对应一 ...
- Windows提高_2.1第一部分:线程
第一部分:线程 什么是线程? 线程其实可以理解为一段正在执行中的代码,它最少由一个线程内核对象和一个栈组成. 线程之间是没有从属关系的,同一进程下的所有线程都可以访问进程内的所有内容. 主线程其实是创 ...
- Windows提高_2.2第二部分:用户区同步
第二部分:用户区同步 同步和互斥 同步:就是按照一定的顺序执行不同的线程 互斥:当一个线程访问某一资源的时候,其它线程不能同时访问 多线程产生的问题 #include <stdio.h> ...
- Windows内核原理-同步IO与异步IO
目录 Windows内核原理-同步IO与异步IO 背景 目的 I/O 同步I/O 异步I/O I/O完成通知 总结 参考文档 Windows内核原理-同步IO与异步IO 背景 在前段时间检查异常连接导 ...
- windows+mysql集群搭建-三分钟搞定集群
注:本文来源: 陈晓婵 < windows+mysql集群搭建-三分钟搞定集群 > 一:mysql集群搭建教程-基础篇 计算机一级考试系统要用集群,目标是把集群搭建起来,保证一 ...
- Windows核心编程 第三章 内核对象
第3章内核对象 在介绍Windows API的时候,首先要讲述内核对象以及它们的句柄.本章将要介绍一些比较抽象的概念,在此并不讨论某个特定内核对象的特性,相反只是介绍适用于所有内核对象的特性. 首先介 ...
- windows核心编程---第三章 内核对象及句柄本质
本章讨论的是相对抽象的概念,不涉及任何具体的内核对象的细节而是讨论所有内核对象的共有特性. 首先让我们来了解一下什么是内核对象.内核对象通过API来创建,每个内核对象是一个数据结构,它对应一块内存 ...
- Windows提高_1.1内核对象
内核对象 什么是内核对象? 内核对象本质上是一个结构体,我们不能直接的操作一个内核对象,需要通过操作系统提供的一系列函数和我们使用的内核对象句柄对它进行一系列的修改. 如何操作内核对象? 创建一个内核 ...
- (ETW) Event Trace for Windows 提高 (含pdf下载)
内容提纲 • 托管代码与非托管代码介绍 • 不安全代码介绍 • 用户模式与内核模式 • ETW执行流程分析 • 日志分析工具介绍:PerfView.exe ETW与非托管代码 • ETW依赖的So ...
随机推荐
- Boss OpenCart 商城自适应主题模板 ABC-0012-01
Boss OpenCart 商城自适应主题模板 ABC-0012-01 模板特性兼容浏览器IE7, IE8, IE9, IE10, Firefox, Safari, Chrome OpenCart版本 ...
- 【WinHec启发录】透过Windows 10技术布局,谈微软王者归来
每一个时代都有王者,王者的成功,往往是由于恰逢其时地公布了一个成功的产品(具有里程碑意义,划时代的产品).Windows 95的成功标示着微软是PC时代的王者:WinXP的成功标示着微软是互联网时代的 ...
- UVa 11582 Colossal Fibonacci Numbers! 【大数幂取模】
题目链接:Uva 11582 [vjudge] watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fil ...
- 【HNOI模拟By lyp】Day1
1 xlk1.1 题目描述 给定一棵大小为 n 的无根树,求满足以下条件的四元组 (a, b, c, d) 的个数: 1. 1 ≤ a < b ≤ n 2. 1 ≤ c < d ≤ n 3 ...
- commons-fileupload 组件实现文件上传
index.jsp 核心代码: //创建文件项工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); //创建解析请求 数据的Servl ...
- fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt
project->xx Properties->Manifest->Input and Output->Embed Manifest将yes修改为no
- android 6.0编译时出现ERROR:Security problem ,see jack server log【转】
本文转载自:http://blog.csdn.net/a567890k/article/details/52956798 最近编译Android6.0时经常出现以下错误 临时解决方法: Buildin ...
- PL/SQL -->隐式游标(SQL%FOUND)
PL/SQL -->隐式游标(SQL%FOUND) 分类: SQL/PLSQL 基础2010-12-22 16:23 4084人阅读 评论(0) 收藏 举报 sqlexceptionoracle ...
- cassandra的全文检索插件
https://github.com/Stratio/cassandra-lucene-index Stratio’s Cassandra Lucene Index Stratio’s Cassand ...
- 解决jQuery uploadify在非IE核心浏览器下无法上传
之前上传了一个通过Flash实现多文件上传,但是在IE正常运行,FireFox 不能正常上传.经过反复研究学习,之所以firefox和360浏览器无法正常运行,是因为FireFox.chrome.36 ...