零基础逆向工程37_Win32_11_事件_线程同步
1 内核对象
前面已经学过线程和互斥体两个内核对象。此节讲了事件这个内核对象。前面提出了内核对象这个概念,可能不太清晰,简单来说内核对象就是系统层的东西。
1.1 小结内核对象:
进程、线程、事件、互斥体、文件、文件映射等。
1.2 事件内核对象的创建
HANDLE g_hEvent = CreateEvent(NULL, TRUE, FALSE, "XYZ");
HANDLE g_hMutex = CreateMutex(NULL,FALSE, "XYZ");
1.3 事件内核对象的获取
HANDLE OpenEvent(
DWORD dwDesiredAccess, // access
BOOL bInheritHandle, // inheritance option
LPCTSTR lpName // object name
);
HANDLE g_hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, "XYZ");
HANDLE g_hMutex = OpenMutex(MUTEX_ALL_ACCESS,FALSE, "XYZ");
1.4 内核对象的销毁
BOOL CloseHandle(HANDLE hobj);
(1)、当没有其他程序引用时,系统会销毁内核对象(使用数量).
(2)、内核对象的生命周期,可能比创建它的对象要长.
2 事件对象
2.1 事件对象的创建
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全属性 NULL时为系统默认
BOOL bManualReset, // TRUE 通过调用ResetEvent将事件对象标记为未通知
BOOL bInitialState, // TRUE 已通知状态 FALSE未通知状态
LPCTSTR lpName // 对象名称 以NULL结尾的字符串
);
2.2 事件对象的控制
BOOL SetEvent(HANDLE hEvent);
2.3 关闭时间对象句柄
CloseHandle();
2.4 线程控制实验:只读形式的线程控制
HANDLE g_hEvent;
HWND hEdit1;
HWND hEdit2;
HWND hEdit3;
HWND hEdit4;
HANDLE hThread1;
HANDLE hThread2;
HANDLE hThread3;
HANDLE hThread4;
DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
//创建事件
//默认安全属性 手动设置未通知状态(TRUE) 初始状态未通知 没有名字
g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
HANDLE hThread[3];
//创建3个线程
hThread[0] = ::CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
hThread[1] = ::CreateThread(NULL, 0, ThreadProc3, NULL, 0, NULL);
hThread[2] = ::CreateThread(NULL, 0, ThreadProc4, NULL, 0, NULL);
//设置文本框的值
SetWindowText(hEdit1,"1000");
//设置事件为已通知
SetEvent(g_hEvent);
//等待线程结束 销毁内核对象
WaitForMultipleObjects(3, hThread, TRUE, INFINITE);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
CloseHandle(hThread[2]);
CloseHandle(g_hEvent);
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
TCHAR szBuffer[10] = {0};
//当事件变成已通知时
WaitForSingleObject(g_hEvent, INFINITE);
//读取内容
GetWindowText(hEdit1,szBuffer,10);
SetWindowText(hEdit2,szBuffer);
return 0;
}
DWORD WINAPI ThreadProc3(LPVOID lpParameter)
{
TCHAR szBuffer[10] = {0};
//当事件变成已通知时
WaitForSingleObject(g_hEvent, INFINITE);
//读取内容
GetWindowText(hEdit1,szBuffer,10);
SetWindowText(hEdit3,szBuffer);
return 0;
}
DWORD WINAPI ThreadProc4(LPVOID lpParameter)
{
TCHAR szBuffer[10] = {0};
//当事件变成已通知时
WaitForSingleObject(g_hEvent, INFINITE);
//读取内容
GetWindowText(hEdit1,szBuffer,10);
SetWindowText(hEdit4,szBuffer);
return 0;
}
3 线程同步
3.1 什么是线程同步?
同步就是协同步调,按预定的先后次序进行运行。如:你说完,我再说。
如进程、线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A再继续操作。
[摘自百度百科]
3.2 事件和临界区
HANDLE g_hSet, g_hClear;
int g_Max = 10;
int g_Number = 0;
//生产者线程函数
DWORD WINAPI ThreadProduct(LPVOID pM)
{
for (int i = 0; i < g_Max; i++)
{
WaitForSingleObject(g_hSet, INFINITE);
g_Number = 1;
DWORD id = GetCurrentThreadId();
printf("生产者%d将数据%d放入缓冲区\n",id, g_Number);
SetEvent(g_hClear);
}
return 0;
}
//消费者线程函数
DWORD WINAPI ThreadConsumer(LPVOID pM)
{
for (int i = 0; i < g_Max; i++)
{
WaitForSingleObject(g_hClear, INFINITE);
g_Number = 0;
DWORD id = GetCurrentThreadId();
printf("----消费者%d将数据%d放入缓冲区\n",id, g_Number);
SetEvent(g_hSet);
}
return 0;
}
int main(int argc, char* argv[])
{
HANDLE hThread[2];
g_hSet = CreateEvent(NULL, FALSE, TRUE, NULL);
g_hClear = CreateEvent(NULL, FALSE, FALSE, NULL);
hThread[0] = ::CreateThread(NULL, 0, ThreadProduct, NULL, 0, NULL);
hThread[1] = ::CreateThread(NULL, 0, ThreadConsumer, NULL, 0, NULL);
WaitForMultipleObjects(2, hThread, TRUE, INFINITE);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
//销毁
CloseHandle(g_hSet);
CloseHandle(g_hClear);
return 0;
}

零基础逆向工程37_Win32_11_事件_线程同步的更多相关文章
- 零基础逆向工程38_Win32_12_信号量_线程控制小结
1 信号量 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用.[百度百科] 1.1 创建信号量 HANDLE Create ...
- 零基础逆向工程28_Win32_02_事件_消息_消息处理函数
1 第一个图形界面程序 步骤1:创建Windows应用程序 选择空项目 步骤2:在新建项窗口中选C++代码文件 创建一个新的cpp文件 步骤3:在新的cpp文件中添加:#include <Win ...
- 零基础逆向工程29_Win32_03_ESP寻址_定位回调函数_子窗口_消息处理函数
1 Win32应用程序入口识别 思路:根据WinMain的四个参数,由调用顺序,知道最后压栈的是hInstance句柄(也就是WinMain函数的第一个参数,其值等于ImageBase),根据反汇编, ...
- 零基础逆向工程20_PE结构04_任意节空白区_新增节_扩大节添加代码
向代码节添加代码实现 作者经过一周不断的失败,再思考以及无数次调试终于实现. 思路:八个步骤 1. 文件拷到文件缓冲区(FileBuffer) //图示见(零基础逆向工程18之PE加载过程) 2. 文 ...
- C#当中的多线程_线程同步
第2章 线程同步 原来以为线程同步就是lock,monitor等呢,看了第二章真是大开眼界啊! 第一章中我们遇到了一个叫做竞争条件的问题.引起的原因是没有进行正确的线程同步.当一个线程在执行操作时候, ...
- [b0034] python 归纳 (十九)_线程同步_条件变量
代码: # -*- coding: utf-8 -*- """ 学习线程同步,使用条件变量 逻辑: 生产消费者模型 一个有3个大小的产品库,一个生产者负责生产,一个消费者 ...
- java ->多线程_线程同步、死锁、等待唤醒机制
线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. l 我们通过一个案例,演示线 ...
- 零基础逆向工程39_Win32_13_进程创建_句柄表_挂起方式创建进程
1 进程的创建过程 打开系统 --> 双击要运行的程序 --> EXE开始执行 步骤一: 当系统启动后,创建一个进程:Explorer.exe(也就是桌面进程) 步骤二: 当用户双击某一个 ...
- 零基础逆向工程34_Win32_08_线程控制_CONTEXT结构
线程控制 实验 挂起线程 ::SuspendThread(hThread); 恢复线程 ::ResumeThread(hThread); 终止线程 (这里讲了同步调用与异步调用) 方式一: 此方法结束 ...
随机推荐
- angular知识点总结
angularjs angular支持的运算 逻辑运算 比较运算 三目运算 调用字符串对象的成员方法 使用直接变量表示法创建对象 使用数组 (不可以)new var (不可以)调用全局es javas ...
- CF351A Jeff and Rounding 思维
Jeff got 2n real numbers a1, a2, ..., a2n as a birthday present. The boy hates non-integer numbers, ...
- 10.Find All Anagrams in a String(在一个字符串中发现所有的目标串排列)
Level: Easy 题目描述: Given a string s and a non-empty string p, find all the start indices of p's ana ...
- Xshell连接不上Ubuntu解决方式
1—— 首先检查一下自己的网络是否正常,如果是插上网线就能用的,就很好:如果是校园网拨号方式上网的,请检查自己是否建立拨号连接. [编辑连接] [添加] PPPOE上网方式选择[DSL] 2—— ...
- python 对三维CT数据缩放
项目需要对CT数据进行缩放,这里我存储CT数据的格式是numpy数组. 一共尝试了三种方法,分别是numpy.resize,cv2.resize,scipy.ndimage.interpolation ...
- win7 宽带连接 711错误
新装Win7系统,建立宽带连接后提示711错误,网上转一圈,方法不少,对症下药,不是很管用 以下是我总结的方法 win7 旗舰版 administration 用户 设置以下几个服务为手动或自动,并启 ...
- Flask&&人工智能AI -- 7 MongoDB
MongoDB初识,增删改查操作,数据类型,$关键字以及$修改器.“$”的奇妙用法,Array Object的特殊操作,选取跳过排序,客户端操作 一.MongoDB初识 什么是MongoDB Mong ...
- 经典SQL行列转换
-- http://www.programbbs.com/doc/4885.htm /* 标题:普通行列转换(version 2.0) 说明:普通行列转换(version 1.0)仅针对sql ser ...
- args 、kwargs不定参数通过列表、元组、字典传递
*args .**kwargs是不定参数的表达方法,一般用于函数形参.*args .**kwargs 作为传递参数的函数,在使用过程中,可对*args .**kwargs多个输入,但是效率或者比较麻烦 ...
- 技巧:开启ubuntu系统的ssh服务
执行下述命令,安装 openssh 服务器. $ sudo apt-get install openssh-server 执行下面命令,启动 openssh $ sudo service ssh st ...