欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

互斥量内核对象

程序员文章站 2022-06-03 17:58:34
...

互斥量对象有许多用途,它是使用最为频繁的内核对象之一,一般用来对多个进程访问同一块内存进行同步。

同一进程中的线程同步用关键段或者Slim读写锁就行,比互斥量要快。

HADNLE CreateMutex(PSECURITY_ATTRIBUTES psa,BOOL bInitialOwner,PCTSTR pszName);

 


bInitialOwner:FALSE:互斥量线程ID和递归计数都将被设置为0,互斥量不被任何线程所占有,处于触发状态。

                     TRUR:互斥量对象的线程ID会设置成调用线程的ID,递归计数变1,互斥量处于未触发状态。

HANDLE OpenMutex(DWORD dwDesiredAccess,BOOL bInheritHandle,PCTSTR pszName);  //第一个参数是限制某些权限 
BOOL ReleaseMutex(HANDLE)  //不再需要访问资源


这个函数将对象的递归次数减一。如果线程等待了不止一次互斥量,必须Release相同次数,当递归次数变成0的时候,函数会将对象中的线程ID设置为0,这样就触发了对象。  当对象被触发的时候,系统会检查有无其他线程正在等待互斥量。如果有,系统将公平的选择一个正在等待的线程,把互斥量的所有权交给它。

在用来触发普通的内核对象和撤销普通的内核对象,有一条不适合互斥量:系统会检查想要获得互斥量线程ID与互斥量对象内部记录的线程ID是否相同,如果相同,那么系统会让线程保持可调度状态,即使该互斥量还处于未触发状态,:让线程多次等待同一个互斥量。(递归计数大于一的唯一途径)

eg:

//test1.cpp

int main()

{   

    HANDLE stream1Mutex = CreateMutex(NULL, false, (LPCWSTR)"streamMutex");   //如果存在就是打开内核对象

  WaitForSingleObject(stream1Mutex, INFINITE);    //刚才创建了是触发状态  现在等待了立马变成未触发状态  另一个进程此时只能等待

    ofstream fileStream1("c:/test.txt", ios_base::app);

    for (int i = 0, j = 1; i < 10; ++i)

    {

        Sleep(1000);

        fileStream1<<j;

        fileStream1<<' '<<flush;

  }

  

    ReleaseMutex(stream1Mutex);

    CloseHandle(stream1Mutex);

}
//test2.cpp

int main()

{

    HANDLE stream2Mutex = CreateMutex(NULL, false, (LPCWSTR)"streamMutex");

    WaitForSingleObject(stream2Mutex, INFINITE);

 

    ofstream fileStream2("c:/test.txt", ios_base::app);

    for (int i = 0, j = 2; i < 10; ++i)

    {

        Sleep(1000);

        fileStream2<<j;

        fileStream2<<' '<<flush;

    }

 

   ReleaseMutex(stream2Mutex);

    CloseHandle(stream2Mutex);

}