4、多线程(2)

我们利用互斥对象来实现线程同步。

互斥对象(mutex)属于内核对象,它能够确保线程拥有对单个资源的互斥访问权。

互斥对象包含一个使用数量,一个线程ID和一个计数器。

ID用于标识系统中的哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数。

创建互斥对象:

HANDLE CreateMutex(

  LPSECURITY_ATTRIBUTES lpMutexAttributes,  // SD

  BOOL bInitialOwner,                       // initial owner

  LPCTSTR lpName                            // object name

);

通过以下ReleaseMutex函数来实现对互斥对象的释放

BOOL ReleaseMutex(

  HANDLE hMutex   // handle to mutex

);

线程必须主动申请共享对象的使用权才有可能获得该所有权,可以通过调用DWORD WaitForSingleObject(

  HANDLE hHandle,        // handle to object

  DWORD dwMilliseconds   // time-out interval

);

来实现。

对于互斥对象来说,它是唯一与线程相关的内核对象。谁拥有,谁释放。

while(TRUE)

{

   WaitForSingleObject(hMutex,INFINITE);

   if(ticket>0)

   {

    cout<<"ticket 2:"<<ticket--<<endl;

   }

   else

    break;

   ReleaseMutex(hMutex);   //不管是主线程还是兄弟线程,谁拥有,谁释放。

}

当调用WaitForSingleObject函数请求互斥对象时,操作系统需要判断当前请求互斥对象的线程的ID是否与互斥对象当前拥有者的线程ID相等,如果相等,即使该互斥对象处于未通知状态,调用线程仍然能够获得其所有权,然后WaitForSingleObject函数返回。对于同一个线程多次拥有的互斥对象来说,该互斥对象内部的计数器记录了该线程拥有的次数。操作系统一旦发现该线程已经终止,它就会自动将该线程所拥有的互斥对象的线程ID设为0,并将其计数器归0

参考

[1] 孙鑫 《深入VC++》

上一篇:3、多线程(1)


下一篇:7、进程间通信-剪贴板