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 :)

Reply via email to