Thread overview
[RFC] "lock" statement and "mutex" type.
Mar 14, 2006
Dejan Lekic
Mar 14, 2006
Sean Kelly
Mar 14, 2006
Dejan Lekic
Mar 14, 2006
BCS
Mar 15, 2006
Dejan Lekic
Mar 15, 2006
Graham St Jack
Mar 15, 2006
Dejan Lekic
Mar 15, 2006
BCS
Mar 15, 2006
Sean Kelly
March 14, 2006
I think D should have mutex type and lock statement as part of D language, in the similar fashion as in Modula-3.

D programmer would than be able to write:

mutex myMutex;

lock (myMutex)
{
  doSomething();
} else {
  continueSomething();
}

What do others think about this?
Reason for this above is that my personal opinion is that D should be the
language with full support for threads. I would even add "thread" keyword
somehow...

Kind regards

Dejan
March 14, 2006
Dejan Lekic wrote:
> I think D should have mutex type and lock statement as part of D language,
> in the similar fashion as in Modula-3.
> 
> D programmer would than be able to write:
> 
> mutex myMutex;
> 
> lock (myMutex)
> {
>   doSomething();
> } else {
>   continueSomething();
> }
> 
> What do others think about this?

I'm not familar with that.  What's the behavior?  Is it a tryLock where the else block handles the failure?  Does the syntax account for lock acquisition with a timeout?  That said, I agree that D needs better concurrency support, and that broader mutex support is one aspect of this.  In particular, I'd at least like to have some way to not wait indefinitely for a lock to become available.


Sean
March 14, 2006
Hi Sean,
yes, i did not think about acquisition with a timeout maybe following syntax
change is what we would like to have:
lock (<mutex variable>[, timeout])

You understood everything else. My was plain simple trylock. Following code is an example of code without try:

lock (myMutex) // blocks calling thread
{
  doSomething();
}

as we slightly changed the main idea (from my previous post), we could have
something like:

lock (myMutex, 1000) // blocks calling thread for 1 second
{                    // if mutex "myMutex" is not unlocked during that time
  doSomething();     // it will exit the lock() block and execute continue()
}                    // function.
continue();


Regards

-----------
Dejan Lekic
  http://dejan.lekic.org
March 14, 2006
The simple tryLock would allow for timeout:

while(!timeout())
{
  lock(mutex)
  {
    go();
    break;
  }
  else
    continue;
}

A bit clunky but...

I'm glad that native support for threads is being considered, I think that it would be a vary good thing. It would allow for some quite nice features like:

thread t1;

t1.run = &fn;	// launch thread

if(t1mustDie) t1.throw new KillThread;	// throw an exception in t1



Dejan Lekic wrote:
> Hi Sean,
> yes, i did not think about acquisition with a timeout maybe following syntax
> change is what we would like to have:
> lock (<mutex variable>[, timeout]) 
> 
> You understood everything else. My was plain simple trylock. Following code
> is an example of code without try:
> 
> lock (myMutex) // blocks calling thread
> {
>   doSomething();
> }
> 
> as we slightly changed the main idea (from my previous post), we could have
> something like:
> 
> lock (myMutex, 1000) // blocks calling thread for 1 second
> {                    // if mutex "myMutex" is not unlocked during that time
>   doSomething();     // it will exit the lock() block and execute continue()
> }                    // function.
> continue();
> 
> 
> Regards
> 
> -----------
> Dejan Lekic
>   http://dejan.lekic.org
March 15, 2006
BCS, on contrary - it is not considered - that is why I began this thread... :) So far all participants in this discussion agrees that D (language) needs this what we discuss. Sure everything depends on Mr. Bright.

-----------
Dejan Lekic
  http://dejan.lekic.org

March 15, 2006
Dejan Lekic wrote:
> BCS, on contrary - it is not considered - that is why I began this
> thread... :) So far all participants in this discussion agrees that D
> (language) needs this what we discuss. Sure everything depends on Mr.
> Bright.
> 
> -----------
> Dejan Lekic
>   http://dejan.lekic.org
> 


I agree that better threading support is needed in D. The synchronized keyword is a great start, but more is needed.

My opinion is that try_lock() on a mutex isn't a good idea - it is better to use conditions. You use mutexes to keep threads "apart" from each other (the synchronized keyword does this very well), making sure that no thread retains a lock for long.

You use conditions to enable a thread to "block" for potentially extended periods, without any thread retaining a lock on the mutex.

A couple of other related posts are:
http://www.digitalmars.com/d/archives/digitalmars/D/31340.html
http://www.digitalmars.com/d/archives/digitalmars/D/34392.html
March 15, 2006
My suggesion in form of lock(someMutex) {} else {} satisfies both type of
concurrent programming fans. If you do not want lock to try, than just
forget else block. :) Without else block lock() would behave like
pthread_mutex_lock(), with else block it would behave like
pthread_mutex_trylock() . Yes, i agree conditional variables should also be
there, however i did not think so much about how to do it...

March 15, 2006
Dejan Lekic wrote:
> My suggesion in form of lock(someMutex) {} else {} satisfies both type of
> concurrent programming fans. If you do not want lock to try, than just
> forget else block. :) Without else block lock() would behave like
> pthread_mutex_lock(), with else block it would behave like
> pthread_mutex_trylock() . Yes, i agree conditional variables should also be
> there, however i did not think so much about how to do it...
> 

One other thought: How should deadlock be handled?

options:
	1> it's not, that's the programmer's problem.
	2> some unspecified, the compiler/runtime just does it.
	3> multiple locks can be requested at the same time e.i.

		lock(mutex1, mutex2) // block untill mutex 1&2 can both be held

	   but no more can be acquired until the first ones are released.

	4> other.
March 15, 2006
BCS wrote:
> Dejan Lekic wrote:
>> My suggesion in form of lock(someMutex) {} else {} satisfies both type of
>> concurrent programming fans. If you do not want lock to try, than just
>> forget else block. :) Without else block lock() would behave like
>> pthread_mutex_lock(), with else block it would behave like
>> pthread_mutex_trylock() . Yes, i agree conditional variables should also be
>> there, however i did not think so much about how to do it...
>>
> 
> One other thought: How should deadlock be handled?
> 
> options:
>     1> it's not, that's the programmer's problem.
>     2> some unspecified, the compiler/runtime just does it.
>     3> multiple locks can be requested at the same time e.i.
> 
>         lock(mutex1, mutex2) // block untill mutex 1&2 can both be held

Either 1 or 3.

>        but no more can be acquired until the first ones are released.

No.  It's not unusual to need more locks later if you're using a lock heirarchy.  Only locks on the same level must be acquired simultaneously.  That said, this whole lock business is a huge pain, and I'm hoping we can do better with D.  Herb Sutter gave a talk on his Concur library for C++ the other day, and the ideas seem pretty reasonable (though he didn't really answer my question on how to handle the possibility of multiple parallel exceptions in C++ -- perhaps not an issue in D).  In any case, I may try doing something similar in D.  I think delegates might make the whole process quite streamlined.


Sean