Avoiding deadlock with mutex trylock in multithreaded app.
Pierre Mallard
mallard.pierre@gmail.com
Sat Aug 8 14:24:00 GMT 2009
Hi,
Sorry for this long mail, and thanks for your help and advice :
I have a question regarding proper handling of non concurrent access
between two (or more) thread that deals together on a
register/unregister + callback way.
Let's try to be clear !
A Threaded Module "A" acts like this :
It offers two function to a module B and has a main task :
"A_register" register request, called by module B in a Start
function, called by a thread "C"
"A_unregister" unregister request , called by module B in a Release
function, in a thread "C"
"A_process" a thread main task that loop forever and unqueue request,
call multiple time the callback that comes with the request untill
request processing is finished and start again
A module B that is driven by a task C that has three function :
"B_start" register to A
"B_callback" calls by A during request processing
"B_release" unregister to A, and destroy B
I need to avoid B_callback to be called during and after B_release
I can think of two way things could work :
A "deadlock way" that leads to a deadlock (!),
A "Trylock way" that requires trylock
I present here both approach and attached a code sample to illustrate
the trylock way I can think of.
I am wondering whether the trylock approach is the good one, and also
how could I avoid the waste of time (and CPU !) trying to lock mutex_B
?
************************************************************
"The deadlock way"
A Module A mutex between callback calls and unregister function, to
check if request is still existing,
A Module B mutex between release and callback.
But that leads to a dead lock :
=====================================
Thread A
=====================================
"A_process" lock mutex_A to check whether request is still registered
if !stop_cur_request
B_Callback lock/unlock mutex_B
unlock mutex_A
=====================================
Thread C
=====================================
"B_release" lock mutex_B
"A_Unregister" lock/unlock mutex A
unlock mutex_B
The dead lock appears because in task A we lock mutex_A then mutex_B
and in task C we lock mutex_B then mutex_A.
***********************************************************
"The TryLock way"
I can Trylock instead of lock in Callback, Therefore, when release is
called and lock mutex_B, callback won't hold mutex_A if it realize
mutex_B is busy.
=====================================
Thread A
=====================================
"A_process"
...
while (TRUE)
lock mutex_A
if !stop_cur_request
if Call Callback == RETRY <-- TryLock Failed
unlock mutex_A
else
break
endif
endif
endWhile
unlock mutex_A
...
Thanks a lot for your attention, comments and advice,
Regards,
Pierre
--
Pierre Mallard
-------------- next part --------------
A non-text attachment was scrubbed...
Name: trylock.c
Type: text/x-csrc
Size: 3610 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-help/attachments/20090808/5c5a6bb2/attachment.bin>
More information about the Libc-help
mailing list