将 initialOwner 设置为 TRUE 的 CreateMutex 使创建者进程保持互斥直到完成

CreateMutex with initialOwner set to TRUE makes the creator process keep the mutex till it's done

我有两个进程,一个写入内存映射文件 - producer - 而另一个从内存文件读取 - consumer.

第一个进程使用 CreateMutex() 函数创建互斥锁,并将 initialOwner 参数设置为 TRUE

代码如下:

制作人:

mutexHandle = CreateMutex(NULL, TRUE, TEXT("producerMutex"));
while (condition)
{
    WaitForSingleObject(mutexHandle, INFINITE);
    // write a random number in the memory mapped file;
    // pause the program and prompt the user to open consumer process; do this only one time 
    ReleaseMutex(mutexHandle);
}

消费者:

mutexHandle = OpenMutex(SYNCRONIZE , FALSE, TEXT("producerMutex"));
while (condition)
{
    WaitForSingleObject(mutexHandle, INFINITE);
    // read from the file, print it in terminal
    ReleaseMutex(mutexHandle);
}

问题是,如果 initialOwner 设置为 TRUE,则在 producer 完成之前,消费者将无法访问互斥锁。这是为什么?如果 initialOwner 设置为 FALSE,应用程序可以工作,但它不应该也可以设置为 TRUE 吗?

initialOwner参数的说明:

CreateMutex function:

If this value is TRUE and the caller created the mutex, the calling thread obtains initial ownership of the mutex object. Otherwise, the calling thread does not obtain ownership of the mutex. To determine if the caller created the mutex, see the Return Values section.

您需要在信息准备好被消费后调用 ReleaseMutex() 互斥量。

来自 ReleaseMutex 文档:

to release its ownership, the thread must call ReleaseMutex one time for each time that it obtained ownership (either through CreateMutex or a wait function).

在此代码中:

mutexHandle = CreateMutex(NULL, TRUE, TEXT("producerMutex"));
while (condition)
{
    WaitForSingleObject(mutexHandle, INFINITE);
    // write a random number in the memory mapped file;
    // pause the program and prompt the user to open consumer process; do this only one time 
    ReleaseMutex(mutexHandle);
}

您获得互斥锁 N+1 次 - 通过 CreateMutex()bInitialOwner=TRUE 获得 1 次,通过 WaitForSingleObject() 在循环中获得 N 次。但是你在循环中只释放它 N 次。结果,在循环之后您仍然持有互斥锁,直到线程退出。

要解决此问题,您需要跳过循环中对 WaitForSingleObject 的第一次调用 - 事实上,您已经是互斥锁的所有者,不需要此调用。你可以这样写代码:

if (mutexHandle = CreateMutex(0, TRUE, L"producerMutex"))
{
    goto __firstTime;
    do 
    {
        WaitForSingleObject(mutexHandle, INFINITE);
__firstTime:
        // write a random number in the memory mapped file;
        ReleaseMutex(mutexHandle);
        // pause the program and prompt the user to open consumer process; do this only one time 
    } while (condition);

    CloseHandle(mutexHandle);
}

您需要在访问完共享资源后立即调用ReleaseMutex()。当您持有互斥锁时,切勿 "pause" 程序。先松手,再暂停。