零基础逆向工程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 只要有一个成为已通报

dw米尔(Mill)iseconds:超时时间

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);

ACCESS,//逻辑代码
ReleaseMutex(g_hMutex);

互斥体与临界区的界别:
1、临界区不得不用来单个进程间的线程控制.
2、互斥体可以设定等待超时,但临界区不可能.
3、线程意外截止时,Mutex可以制止无限等待.
4、Mutex功能没有临界区高.

5 磨炼项目

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

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

相关文章