互斥量内核对象
程序员文章站
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);
}