Reputation: 1465
I have two processes, one writes in a memory mapped file - the producer
- while the other reads from the memory file - the consumer
.
The first process creates the mutex using the CreateMutex()
function with the initialOwner
parameter set to TRUE
The code is as follows:
producer:
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);
}
consumer:
mutexHandle = OpenMutex(SYNCRONIZE , FALSE, TEXT("producerMutex"));
while (condition)
{
WaitForSingleObject(mutexHandle, INFINITE);
// read from the file, print it in terminal
ReleaseMutex(mutexHandle);
}
The problem is that if the initialOwner
is set to TRUE
the consumer will not get access to the mutex until the producer
is done. Why is that? The application works if the initialOwner
is set to FALSE
, but shouldn't it work with it set on TRUE
as well?
Upvotes: 0
Views: 1031
Reputation: 8174
Look at the description of the initialOwner
parameter:
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.
You need to call ReleaseMutex()
on the mutex after information is ready to be consumed.
Upvotes: -1
Reputation: 33754
From the ReleaseMutex
documentation:
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).
In this code:
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);
}
You obtaining the mutex lock N+1
times - 1 time via CreateMutex()
with bInitialOwner=TRUE
, and N
times in the loop via WaitForSingleObject()
. But you release it only N
times in the loop. As a result, you still hold the mutex lock after the loop, until the thread exits.
To resolve this, you need to skip the first call to WaitForSingleObject
in the loop - really, you are already the owner of the mutex and this call is not needed. You can write code like this:
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);
}
You need to call ReleaseMutex()
just after you finish accessing the shared resource. Never "pause" the program while you hold the mutex lock. First release it, then pause.
Upvotes: 2