1 引言

讲了第二个内核对象,互斥体。前面已经学过一个内核对象,线程。这节讲两个函数,WaitForSingleObject()和WaitForMultipleObjects()。因此这两个函数是根据内核对象的状态来进行操作的。

临界区:一个进程里面对线程进行互斥的控制。

互斥体:实现跨进程的互斥的控制。多个进程抢同一个全局变量,怎样保证最终只有一个进程来用。

2 ForSingleObject()

DWORD WaitForSingleObject(
HANDLE hHandle, // handle to object
DWORD dwMilliseconds // time-out interval
);

功能说明:

等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为已通知状态为止.

hHandle:

内核对象句柄,可以是进程也可以是线程.

dwMilliseconds:

等待时间,单位是毫秒 INFINITE(-1)一直等待

返回值:

WAIT_OBJECT_0(0) 等待对象变为已通知

WAIT_TIMEOUT(0x102) 超时

特别说明:

1、内核对象中的每种对象都可以说是处于已通知或未通知的状态之中

2、这种状态的切换是由Microsoft为每个对象建立的一套规则来决定的

3、当线程正在运行的时候,线程内核对象处于未通知状态

4、当线程终止运行的时候,它就变为已通知状态

5、在内核中就是个BOOL值,运行时FALSE 结束TRUE

代码演示

DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
for(int i=0;i<5;i++)
{
printf("+++++++++\n");
Sleep(1000);
}
return 0;
} int main(int argc, char* argv[])
{ //创建一个新的线程
HANDLE hThread1 = ::CreateThread(NULL, 0, ThreadProc1,
NULL, 0, NULL); DWORD dwCode = ::WaitForSingleObject(hThread1, INFINITE); MessageBox(0,0,0,0); return 0;
}

3 和WaitForMultipleObjects()

DWORD WaitForMultipleObjects(
DWORD nCount, // number of handles in array
CONST HANDLE *lpHandles, // object-handle array
BOOL bWaitAll, // wait option
DWORD dwMilliseconds // time-out interval
);

功能说明:同时查看若干个内核对象的已通知状态

nCount:要查看内核对象的数量

lpHandles:内核对象数组

bWaitAll:等到类型 TRUE 等到所有变为已通知 FALSE 只要有一个变为已通知

dwMilliseconds:超时时间

INFINITE一直等待

返回值:

bWaitAll为TRUE时,返回WAIT_OBJECT_0(0) 代码所以内核对象都变成已通知

bWaitAll为FALSE时,返回最先变成已通知的内核对象在数组中的索引

WAIT_TIMEOUT(0x102)

代码演示:

DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
for(int i=0;i<5;i++)
{
printf("+++++++++\n");
Sleep(1000);
}
return 0;
} DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
for(int i=0;i<3;i++)
{
printf("---------\n");
Sleep(1000);
} return 0;
} int main(int argc, char* argv[])
{ HANDLE hArray[2]; //创建一个新的线程
HANDLE hThread1 = ::CreateThread(NULL, 0, ThreadProc1,
NULL, 0, NULL); //创建一个新的线程
HANDLE hThread2 = ::CreateThread(NULL, 0, ThreadProc2,
NULL, 0, NULL); hArray[0] = hThread1;
hArray[1] = hThread2; DWORD dwCode = ::WaitForMultipleObjects(2, hArray,FALSE,INFINITE); MessageBox(0,0,0,0); return 0;
}

4 跨进程的线程控制与互斥体

进程一:

HANDLE g_hMutex = CreateMutex(NULL,FALSE, "XYZ");

进程二:

HANDLE g_hMutex = OpenMutex(MUTEX_ALL_ACCESS,FALSE, "XYZ");

WaitForSingleObject(g_hMutex,INFINITE);

//逻辑代码

ReleaseMutex(g_hMutex);

进程三:

HANDLE g_hMutex = OpenMutex(MUTEX_ALL_ACCESS,FALSE, "XYZ");

WaitForSingleObject(g_hMutex,INFINITE);

//逻辑代码

ReleaseMutex(g_hMutex);

互斥体与临界区的区别:

1、临界区只能用于单个进程间的线程控制.

2、互斥体可以设定等待超时,但临界区不能.

3、线程意外终结时,Mutex可以避免无限等待.

4、Mutex效率没有临界区高.

5 练习项目

做一个抢红包项目,要求如下

第一步:在第一个文本框中输入一个值,比如1000
第二步:点击抢红包,同时创建3个线程,每个线程循环进行抢红包的操作,每次抢50
第三步:使用Mutex进行线程控制,当第一个文本框中的值<50时,强红包线程结束.
特别说明:
1、四个文本框中的值总和应该为1000
2、强红包线程每次延时50毫秒.
3、使用WaitForMultipleObjects监听所有线程,当线程全部结束后
调用CloseHandle关闭句柄.

零基础逆向工程36_Win32_10_互斥体_互斥体与临界区的区别的更多相关文章

  1. 零基础逆向工程39_Win32_13_进程创建_句柄表_挂起方式创建进程

    1 进程的创建过程 打开系统 --> 双击要运行的程序 --> EXE开始执行 步骤一: 当系统启动后,创建一个进程:Explorer.exe(也就是桌面进程) 步骤二: 当用户双击某一个 ...

  2. 零基础逆向工程40_Win32_14_枚举窗口_模拟鼠标键盘

    1 查找窗口 1.1 代码案例 //查找指定窗口 TCHAR szTitle[MAX_PATH] = {0}; HWND hwnd = ::FindWindow(TEXT("#32770&q ...

  3. 零基础逆向工程31_Win32_05_提取图标_修改标题

    在程序中使用图标 1.加载图标 HICON hIcon; hIcon = LoadIcon (hAppInstance, MAKEINTRESOURCE (IDI_ICON)); hAppInstan ...

  4. 零基础逆向工程30_Win32_04_资源文件_消息断点

    1 资源文件,创建对话框 详细步骤: 1.创建一个空的Win32应用程序 2.在VC6中新增资源 File -> New -> Resource Script 创建成功后会新增2个文件:x ...

  5. 零基础逆向工程20_PE结构04_任意节空白区_新增节_扩大节添加代码

    向代码节添加代码实现 作者经过一周不断的失败,再思考以及无数次调试终于实现. 思路:八个步骤 1. 文件拷到文件缓冲区(FileBuffer) //图示见(零基础逆向工程18之PE加载过程) 2. 文 ...

  6. 零基础逆向工程38_Win32_12_信号量_线程控制小结

    1 信号量 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用.[百度百科] 1.1 创建信号量 HANDLE Create ...

  7. 零基础逆向工程11_C语言05_结构体

    结构体小结 结构体是按照分配的大小,局部变量会自动数据对齐 1字节对齐,省空间,但cpu查找效率低 4字节对齐,不省空间,但cpu查找效率高 VC6默认的结构对齐大小 项目右键-> settin ...

  8. 零基础逆向工程37_Win32_11_事件_线程同步

    1 内核对象 前面已经学过线程和互斥体两个内核对象.此节讲了事件这个内核对象.前面提出了内核对象这个概念,可能不太清晰,简单来说内核对象就是系统层的东西. 1.1 小结内核对象: 进程.线程.事件.互 ...

  9. 零基础逆向工程29_Win32_03_ESP寻址_定位回调函数_子窗口_消息处理函数

    1 Win32应用程序入口识别 思路:根据WinMain的四个参数,由调用顺序,知道最后压栈的是hInstance句柄(也就是WinMain函数的第一个参数,其值等于ImageBase),根据反汇编, ...

随机推荐

  1. CI框架定义判断POST GET AJAX

    CI框架当中并没有提供,类似tp框架中IS_POST,IS_AJAX,IS_GET的方法. 所有就得我们自己造轮子了.下面就介绍一下,如何定义这些判断请求的方法.其实很简单的. 首先打开constan ...

  2. Jmeter-无法启动,'findstr'不是内部或外部命令,也不是可运行的程序

    今天有一个同事的jmeter无法安装,于是帮他看了看,报以下错误: JAVA的环境变量没有配置好,于是重新配置了下环境变量后,再启动,发现还是不好,于是网上查了下, 发现要在电脑的环境变量中增加 pa ...

  3. JavaScript学习笔记——1.了解JavaScript

    百度百科: JavaScript是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果.通常JavaScript脚本是通过嵌入在HT ...

  4. IDEA mybatis-generator 逆向工程

    1.在maven工程中的resource中创建generatorConfig.xml 2.配置generatorConfig.xml <?xml version="1.0" ...

  5. 获取3个月前的时间(获取某一天的时间 NSDate) --NSCalendar--NSDateComponents

    -(void)getThreeMonthDate:(NSDate *)mydate { NSLog(@"%@",mydate); //1.创建NSCalendar NSCalend ...

  6. Qt 学习之路 2(9):资源文件

    Qt 学习之路 2(9):资源文件  豆子  2012年8月31日  Qt 学习之路 2  62条评论 上一章节中我们介绍了如何使用QAction添加动作.其中,我们使用QIcon加载了一张 png ...

  7. java 获取 正在执行的方法名

    //获取调用该方法的方法名.... String method = Thread.currentThread().getStackTrace()[2].getMethodName(); //获取正在执 ...

  8. poj3713 Transferring Sylla 枚举+tarjan判割点

    其实就是判断是否为三连通图 三连通图指的是去掉3个点就不连通的图,但是并没有直接求三连通的算法.著名的Tarjan算法可以求解连通和割点,再枚举删除一个点就能达到三连通的目的. 先看用例2,是由用例1 ...

  9. 杭电ACM hdu 2079 选课时间 (模板)

    Problem Description 又到了选课的时间了,xhd看着选课表发呆,为了想让下一学期好过点,他想知道学n个学分共有多少组合.你来帮帮他吧.(xhd认为一样学分的课没区别) Input输入 ...

  10. shell编程上

    1.1  前言 1.1.1  为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应用软件的核心大都涉及Shel ...