[thread] unlock on multiple lockables

Hi, I don't know if I have already requested that but ... Is there any deep reason to don't provide the equivalent of the free functions lock, try_lock Non-member function lock(Lockable1,Lockable2,...) Non-member function lock(begin,end) Non-member function try_lock(Lockable1,Lockable2,...) Non-member function try_lock(begin,end) to unlock multiple lockables? Non-member function unlock(Lockable1,Lockable2,...) Non-member function unlock(begin,end) Thanks, Vicente -- View this message in context: http://old.nabble.com/-thread--unlock-on-multiple-lockables-tp26471789p26471... Sent from the Boost - Dev mailing list archive at Nabble.com.

On Mon, Nov 23, 2009 at 10:08 AM, Vicente Botet Escriba <vicente.botet@wanadoo.fr> wrote:
Hi,
I don't know if I have already requested that but ...
Is there any deep reason to don't provide the equivalent of the free functions lock, try_lock
Non-member function lock(Lockable1,Lockable2,...) Non-member function lock(begin,end) Non-member function try_lock(Lockable1,Lockable2,...) Non-member function try_lock(begin,end)
to unlock multiple lockables?
Non-member function unlock(Lockable1,Lockable2,...) Non-member function unlock(begin,end)
Probably because locking order can cause deadlocks if the order is different for each locker, but unlocking does not. I assume that the multi-arg locking functions are a way to ensure that there is a globally-defined lock ordering (usually implemented by sorting according to address of mutex). Since unlocking does not have deadlock problems due to unlocking order, it was probably deemed unnecessary to have multi-arg unlocking. Of course, now that you mention it, a multi-unlock would probably be somewhat convenient in a few cases. Sincerely, AmkG

On Sun, Nov 22, 2009 at 9:08 PM, Vicente Botet Escriba <vicente.botet@wanadoo.fr> wrote:
Hi,
I don't know if I have already requested that but ...
Is there any deep reason to don't provide the equivalent of the free functions lock, try_lock
My guesses at the reasons:
Non-member function lock(Lockable1,Lockable2,...) Non-member function lock(begin,end)
Locking a bunch of locks is a recipe for deadlock. Do we lock them in order? Then hold lock1, lock2, waiting to get lock3? Sounds dangerous. On the other hand, I suppose you could argue that using these functions (exclusively) could guarantee that locks were always locked in the same order (thus preventing deadlock)?
Non-member function try_lock(Lockable1,Lockable2,...) Non-member function try_lock(begin,end)
Sounds even scarier - after trying lock1, do you try lock2? - so you don't get lock1, you do get lock2, other thread gets the opposite == deadlock.
to unlock multiple lockables?
Non-member function unlock(Lockable1,Lockable2,...) Non-member function unlock(begin,end)
Thanks, Vicente --
Only other reason would be because they are not common enough, and easy enough to write on your own (using for_each, etc) for when you do need them. Oh, and lastly, because in general direct calls to lock/unlock are discouraged (although at times useful/necessary) and scope_lock is preferred. So if you really wanted multiple locks, a multi_lock class should be used. It's lock() function would lock a set of locks, etc. Then use scope_lock. Tony

Am Monday 23 November 2009 07:30:09 schrieb Gottlob Frege:
On Sun, Nov 22, 2009 at 9:08 PM, Vicente Botet Escriba
<vicente.botet@wanadoo.fr> wrote:
Hi,
I don't know if I have already requested that but ...
Is there any deep reason to don't provide the equivalent of the free functions lock, try_lock
My guesses at the reasons:
Non-member function lock(Lockable1,Lockable2,...) Non-member function lock(begin,end)
Locking a bunch of locks is a recipe for deadlock. Do we lock them in order? Then hold lock1, lock2, waiting to get lock3? Sounds dangerous.
look at the documentation, it locks them in an unspecified order that avoids deadlock - so probably sorted in some arbitrary but stable way, like by the address of the mutex objects.
On the other hand, I suppose you could argue that using these functions (exclusively) could guarantee that locks were always locked in the same order (thus preventing deadlock)?
Non-member function try_lock(Lockable1,Lockable2,...) Non-member function try_lock(begin,end)
Sounds even scarier - after trying lock1, do you try lock2? - so you don't get lock1, you do get lock2, other thread gets the opposite == deadlock.
it locks all or none. to the question: I guess you're guessing right. the order in which mutexes are unlocked doesn't matter, so you can use individual unlock() calls. that try_lock(begin,end) doesn't work btw. it uses some non-existent SFNIA (ok, that's society for neuroscience according to google. you know what I mean) on default arguments, that only MSVC "supports", to detect if you passed two iterators or two Lockables. might be fixed now though, I still use 1.38.

Gottlob Frege <gottlobfrege@gmail.com> writes:
On Sun, Nov 22, 2009 at 9:08 PM, Vicente Botet Escriba <vicente.botet@wanadoo.fr> wrote:
Hi,
I don't know if I have already requested that but ...
Is there any deep reason to don't provide the equivalent of the free functions lock, try_lock
My guesses at the reasons:
Non-member function lock(Lockable1,Lockable2,...) Non-member function lock(begin,end)
Locking a bunch of locks is a recipe for deadlock. Do we lock them in order? Then hold lock1, lock2, waiting to get lock3? Sounds dangerous.
That's why these functions (which are part of the current boost release) don't lock in order, they use a try-and-back-off algorithm to avoid deadlock.
Non-member function try_lock(Lockable1,Lockable2,...) Non-member function try_lock(begin,end)
Sounds even scarier - after trying lock1, do you try lock2? - so you don't get lock1, you do get lock2, other thread gets the opposite == deadlock.
Again, there is no risk of deadlock here. If a thread fails to acquire one of the locks it releases all the locks it has acquired so far.
to unlock multiple lockables?
Non-member function unlock(Lockable1,Lockable2,...) Non-member function unlock(begin,end)
Only other reason would be because they are not common enough, and easy enough to write on your own (using for_each, etc) for when you do need them.
Precisely. You can just call unlock on each item in turn. There are no complications here: you must own the locks to be able to call unlock, and the order doesn't matter.
Oh, and lastly, because in general direct calls to lock/unlock are discouraged (although at times useful/necessary) and scope_lock is preferred.
Sort of. If your locks are scoped to the current block with unique_lock or lock_guard then you don't need to use a block-unlock function, even if you used lock() to acquire them all (having constructed the unique_lock instances with defer_lock). Anthony -- Author of C++ Concurrency in Action | http://www.stdthread.co.uk/book/ just::thread C++0x thread library | http://www.stdthread.co.uk Just Software Solutions Ltd | http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

On Mon, Nov 23, 2009 at 7:02 AM, Anthony Williams <anthony.ajw@gmail.com> wrote:
Gottlob Frege <gottlobfrege@gmail.com> writes:
On Sun, Nov 22, 2009 at 9:08 PM, Vicente Botet Escriba <vicente.botet@wanadoo.fr> wrote:
Hi,
I don't know if I have already requested that but ...
Is there any deep reason to don't provide the equivalent of the free functions lock, try_lock
Sorry everyone, I misunderstood the question. I thought *none* of these functions existed, and was asking why. It's nice to see that there is a deadlock-avoiding lock-multiple (as long as it is used consistently!) Tony
participants (5)
-
Alan Manuel Gloria
-
Anthony Williams
-
Gottlob Frege
-
Stefan Strasser
-
Vicente Botet Escriba