零基础逆向工程36_Win32_10_互斥体_互斥体与临界区底分别

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关闭句柄. 

相关文章