What sync object should i use?

Heinz thor587 at gmail.com
Tue May 14 10:59:51 PDT 2013


Guys, this is a precise example of what i'm trying to do. You'll 
notice that there're 2 ways of waking up the consumer:

/////////////////////////////////////////////////////////////////////
Condition cond; // Previously instantiated.
bool loop = false; // This variable determine if the consumer 
should take the next iteration or wait until a thread calls 
SetLoop(true).
Object my_variable; // A value used for comunicating producer and 
consumer. It's not a prerequisite to be set for an iteration to 
happen.

// This function is called by multiple threads.
void SetLoop(bool val)
{
	if(val != loop)
	{
		loop = val;
		if(loop)
			cond.notify(); // Wake up consumer in case it was waiting.
	}
}

// This function is called by multiple threads.
bool GetLoop()
{
	return loop;
}

void MyConsumer()
{
	while(true)
	{
		synchronized(cond.mutex)
		{
			if(loop == false)
				cond.wait(); // Wait for producer or SetLoop(true).
			
			if(my_variable !is null)
			{
				/*
				...
				Call private function 1. SetLoop(true/false) might be called 
here.
				...
				*/
				my_variable = null; // Lock is useful here for setting 
my_variable.
			}
			
			// These conditions are intentionally placed here.
			if(loop == false)
				continue; // Jump to next iteration. Please note that 
cond.mutex gets released and reaquired in the next iteration.
			else
				loop = false; // Reset waiting on every iteration. Can be 
modified by private function 2 below.
			
			/*
			...
			Call private function 2. SetLoop(true/false) might be called 
here.
			...
			*/
		}
	}
}

void MyProducer()
{
	while(true)
	{
		if(/* Some other condition */)
		{
			synchronized(cond.mutex) // Lock is useful here for setting 
my_variable.
			{
				my_variable = /* Some value */;
				cond.notify(); // Wake up consumer in case it was waiting.
			}
		}
	}
}
/////////////////////////////////////////////////////////////////////

Wouldn't wrapping all the lines in "SetLoop()" inside a 
"synchronized(cond.mutex)" statement produce a deadlock because 
it might be called by private functions 1 or 2? Should i only 
wrap cond.notify() or is it of no meaning in this case? Like this:

void SetLoop(bool val)
{
	if(val != loop)
	{
		loop = val;
		if(loop)
		{
			synchronized(cond.mutex)
				cond.notify(); // Wake up consumer in case it was waiting.
		}
	}
}

Synchronization of variable "loop" doesn't seem important in this 
case. Do you still recommend to use an extra mutex to set it? 
like this:

void SetLoop(bool val)
{
	synchronized(extra_mutex)
	{
		if(val != loop)
		{
			loop = val;
			if(loop)
			{
				synchronized(cond.mutex)
					cond.notify(); // Wake up consumer in case it was waiting.
			}
		}
	}
}

void MyConsumer()
{
	//...
	if(loop == false)
		continue;
	else
	{
		synchronized(extra_mutex)
			loop = false;
	}
	//...
}

Thank you guys so much for your time and your expertise.


More information about the Digitalmars-d-learn mailing list