Implementing a Monitor

Minas minas_mina1990 at hotmail.co.uk
Tue Jul 31 13:19:41 PDT 2012


Thank you for your reply.

I have some more questions:

I simplified my example. Now my monitor is used for mutual 
exclusion, to understand how monitors work first.

// 3 threads are running P() - the main thread is not one of them

void P()
{
	while( run )
	{
		monitor.EnterCritical2();
		
		// critical section
		writeln(count);
		
		monitor.ExitCritical2();
	}
}

class Monitor
{
	Mutex mutex;
	Cond cond;
	bool in_use = false;
	
	this()
	{
		mutex = new Mutex();
		cond = new Cond(mutex);
	}
	
	void EnterCritical()
	{
		// The synchronized statement is required to ensure only one 
thread will be able
		// to access the block
		synchronized(mutex)
		{
			while( in_use )
				cwait(cond);	
			in_use = true;
			
			++count;
		}
	}
	
	void ExitCritical()
	{
		synchronized(mutex)
		{
			--count;
			
			in_use = false;
			cnotify(cond);
		}
	}
}

1) In class (in college), I have learned that monitors "by 
nature" grant access only to one thread in their functions. 
That's what synchronized(mutex) is used for right?

2) Why synchronized(mutex) and not synchronized(this) (I know 
this is not good practise, but is there something more?) or not 
synchronized(some else object)?

3) You correctly changed my "EnterCritical()" code to "While" 
instead of "if", because, and please correct me if I'm wrong, we 
are using notify() and not signal().

4) I wrote my own version of signal. It's:
void csignal(Condition cond)
{
	cond.notify();
	Thread.yield();
}

The logic is that it notifies another Thread and then forces a 
context switch, so it's like calling signal(). Is it correct?

I changed my EnterCritical() to use "if" instead of "while" 
because I use my own version of signal() in ExitCritical().

void EnterCritical2()
	{
		synchronized(mutex)
		{
			if( in_use )
				cwait(cond);
			in_use = true;
			
			++count;
		}
	}
	
	void ExitCritical2()
	{
		synchronized(mutex)
		{
			--count;
			
			in_use = false;
			csignal(cond);
		}
	}

However, when "count" is printed in P(), its value is 3 (it was 1 
before which it ensured that mutual exclusion was correct). If I 
change the "if" to "while" it works, but that's not the purpose 
of signal(). I'm pretty sure that when using "signal" it's "if", 
not "while". What am I doing wrong?


5) Are the threads running concurrently on one core or in 
parallel (provided that the PC has more than one cores). Mine has 
2 cores x 2 threads each.

Thank you.

PS: I'm writing some small programs that demonstrate concurrency 
in D. The reason is I suggested it to my university professor as 
a way to learn about this stuff in a practical manner. So I guess 
if he likes them, D will be tought in a university :)


More information about the Digitalmars-d-learn mailing list