I need help with the following:
I'm learning Synchronization and read about Dijkstra mutex:
Code:
indivisible access routines:
V(s): [s = s + 1]
P(s): [while(s == 0) {wait}; s = s - 1]
The square braces surrounding the statements in the access routines indicate that the operations
are indivisible, or atomic, operations.
The P operation is intended to indivisibly test an integer variable and to block the calling
process if the variable is not positive. The V operation indivisibly signals a blocked
process to allow it to resume operation
And have example with balance management:
Code:
suppose that two processes, p1 and p2, execute concurrently
to access a common integer variable, balance. For example, thread p1 might handle credits
to an account, while p2 handles the debits.
Solution that uses mutex is:
Code:
proc_0() { proc_1() {
... ...
/* Enter critical section */ /* Enter critical section */
P(mutex); P(mutex);
balance = balance + amount; balance = balance - amount;
/* Exit critical section */ /* Exit critical section */
V(mutex); V(mutex);
... ...
} }
semaphore mutex = 1;
fork(proc_0, 0);
fork(proc_1, 0);
I do understand conceptually this explanation, but problem is how to use that with functions such as CreateMutex() and ReleaseMutex().
I'm having problems to understand how following example really works
Code:
a word processor program creates two threads, one to read a file and another to write to a file. Everything is fine at first, the first thread waits for the second to finish writing to the file before reading it. The two threads work happily, everything is fine as long as the writing thread always writes first.
Solution code to this problem is:
Code:
#include <windows.h>
#include <iostream>
HANDLE hMutex, hWriteDone, hReadDone;
int num, state;
void Writer()
{
for(int x=9; x>=0; x--)
{
while(true)
{
if (WaitForSingleObject(hMutex, INFINITE) == WAIT_FAILED)
{
std::cout<<"In writing loop, no mutex!\n";
ExitThread(0);
}
if (state == 0)
{
ReleaseMutex(hMutex);
WaitForSingleObject(hReadDone, INFINITE);
continue;
}
break;
}
std::cout<<"Write done\n";
num= x;
state= 0;
ReleaseMutex(hMutex);
PulseEvent(hWriteDone);
}
}
void Reader()
{
while(true)
{
if (WaitForSingleObject(hMutex, INFINITE) == WAIT_FAILED)
{
std::cout<<"In reader, no mutex!\n";
ExitThread(0);
}
if (state == 1)
{
ReleaseMutex(hMutex);
WaitForSingleObject(hWriteDone, INFINITE);
continue;
}
if (num == 0)
{
std::cout<<"End of data\n";
ReleaseMutex(hMutex);
ExitThread(0);
}
else
{
std::cout<<"Read done\n";
state=1;
ReleaseMutex(hMutex);
PulseEvent(hReadDone);
}
}
}
int main()
{
HANDLE TName[2];
DWORD ThreadID;
state= 1;
hMutex= CreateMutex(NULL, FALSE, NULL);
hWriteDone= CreateEvent(NULL, TRUE, FALSE, NULL);
hReadDone= CreateEvent(NULL, TRUE, FALSE, NULL);
TName[0]= CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)Writer,
NULL, 0, &ThreadID);
TName[1]= CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)Reader,
NULL, 0, &ThreadID);
WaitForMultipleObjects(2, TName, TRUE, INFINITE);
CloseHandle(TName);
}
I realised that these problem are not the same, one is critical section problem sharing variable, other is solving race condition. But, I tried to think variable state as mutex in first example and didn't manage to make analogy. P(mutex) decrement int variable, and V(mutex) increment it. In the second example Writer function sets state to zero and Reader sets state to 1.
Maybe I'm on the wrong track from the begining.
I'm very new (start this morninig) to all this functions(WaitForSingle/MultipleObjects...etc), so
I would ask if someone is kind to explain me on second example how this mechanism really works what is going on and how these functions doing such great job.
I don't know if this is too much for a single thread on this forum, but you all helped me a lot before and hope will help me in future.
Thanks in advance