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. 将已有项目同步到远程git仓库(github,gitee)及giteee的visual studio插件使用一二

    一.将已有项目同步到远程仓库的最简便方法是用git bash: 将已有项目同步到远程仓库有两种方法:1用git bash:2.用vs插件,两者的思路和步骤基本一致的. 实验发现,如果用vs插件,bas ...

  2. Gym - 101845K 排序+概率

    The UNAL programming coaches have lost a bet, they bet the 6 UNAL teams would occupy the first six p ...

  3. django 异常问题总结

    1.问题1 在继承的类中: 403错误: views 添加:from django.core.context_processors import csrf def TestUEditor(reques ...

  4. [Android UI]View基础知识

    一.简介 在安卓中,View代表视图,是安卓中十分重要的一个概念,重要程度不亚于四大组件,用户每时每刻都在与View打交道,包括展示数据.事件传递等.因此,熟练掌握View的应用以及原理是Androi ...

  5. [ZJOI2014]力(FFT)

    [Luogu3338] [BZOJ5327] (DarkBZOJ数据有问题) \(19.3.8\) 前置知识:[知乎-如何通俗易懂地解释卷积] [FFT详解] \(1.\)卷积定义 我们称 \((f* ...

  6. c#缓存帮助类

    public static class CacheHelper { static object _lockObj = new object(); private static Dictionary&l ...

  7. python3 关键字和可变参数笔记

    """普及一下字典的知识""" # dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First' ...

  8. ajaxfileupload.js异步上传

    转载:https://www.cnblogs.com/labimeilexin/p/6742647.html jQuery插件之ajaxFileUpload     ajaxFileUpload.js ...

  9. spring aop实现log 日志跟踪

    之前写的那篇是基于springboot的(https://www.cnblogs.com/yaoyuan2/p/10302802.html),由于遗留项目用的是spring,因此需要在spring基础 ...

  10. php数组·的方法-数组排序

    /* * * 数组排序函数*/ //asort() 数组元素值升序排序 //arsort() 降序 $arr7=array(1,23,65,34,3,2,3,34,453,54,456,65,5); ...