digitalmars.D.learn - Mutexes and locking
- alexhairyman (20/20) Mar 02 2014 I think I'm missing something big, but I'm having troubles with
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (8/28) Mar 02 2014 The documentation says that Mutex is a recursive lock, meaning that the
- alexhairyman (26/61) Mar 03 2014 Okay, so when doing something like this
- yazd (5/73) Mar 03 2014 You have to remember that global scope variables are thread-local
- Sean Kelly (7/7) Mar 04 2014 For what it's worth, you can also do:
- Jeremy DeHaan (11/15) Mar 05 2014 Maybe this is because I haven't done much work with
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (18/30) Mar 05 2014 Same here. :) I have learned about this concept years ago at a company
- Kagamin (7/7) Mar 06 2014 We use non-recursive locks too. The pattern is:
I think I'm missing something big, but I'm having troubles with mutexes (using in a parallel foreach loop somewhere else); Why do the trylocks return true shouldn't they return false because the mutex is already locked? I don't think this is a phobos bug, I'm on OSX using dmd 2.065 import core.sync.mutex; import std.stdio; void main() { Mutex m = new Mutex; m.lock(); writefln("%s", m.tryLock()); writefln("%s", m.tryLock()); return; } produces: true true Thanks! Alex
Mar 02 2014
On 03/02/2014 10:38 PM, alexhairyman wrote:I think I'm missing something big, but I'm having troubles with mutexes (using in a parallel foreach loop somewhere else); Why do the trylocks return true shouldn't they return false because the mutex is already locked?The documentation says that Mutex is a recursive lock, meaning that the holder of the lock can lock it even further. :) There is an internal reference count so that the lock must be unlocked the equal number of times that it has been locked.I don't think this is a phobos bug, I'm on OSX using dmd 2.065 import core.sync.mutex; import std.stdio; void main() { Mutex m = new Mutex; m.lock(); writefln("%s", m.tryLock()); writefln("%s", m.tryLock());The lock count is now 3. You must unlock it 3 times so that another thread can lock it.return; } produces: true true Thanks! AlexAli
Mar 02 2014
On Monday, 3 March 2014 at 07:38:05 UTC, Ali Çehreli wrote:On 03/02/2014 10:38 PM, alexhairyman wrote:Oh okay, that makes sense.I think I'm missing something big, but I'm having troubleswith mutexes(using in a parallel foreach loop somewhere else); Why do thetrylocksreturn true shouldn't they return false because the mutex isalreadylocked?The documentation says that Mutex is a recursive lock, meaning that the holder of the lock can lock it even further. :) There is an internal reference count so that the lock must be unlocked the equal number of times that it has been locked.Okay, so when doing something like this Mutex hashlock; void tdigest(string path) { MD5Digest thasher = new MD5Digest; thasher.put(read(path)); //read the path in to the MD5 API hashlock.lock(); hashkey[path] = thasher.finish(); hashlock.unlock(); } void main() { hashlock = new Mutex(); ... other stuff foreach(string s ; tp.parallel(array of strings)) { tdigest(s); } ... even more stuff } it will fail because the parallel foreach uses the main thread is being used which does some funky stuff? I'm trying to figure out how to implement this (for reference I'm just trying to create a big hash map of files and their md5's)I don't think this is a phobos bug, I'm on OSX using dmd 2.065 import core.sync.mutex; import std.stdio; void main() { Mutex m = new Mutex; m.lock(); writefln("%s", m.tryLock()); writefln("%s", m.tryLock());The lock count is now 3. You must unlock it 3 times so that another thread can lock it.return; } produces: true true Thanks! AlexAli
Mar 03 2014
On Monday, 3 March 2014 at 08:18:04 UTC, alexhairyman wrote:On Monday, 3 March 2014 at 07:38:05 UTC, Ali Çehreli wrote:You have to remember that global scope variables are thread-local by default. So your hashlock mutex is actually only initialized in the main thread. Try adding __gshared before declaring hashlock and see if it works.On 03/02/2014 10:38 PM, alexhairyman wrote:Oh okay, that makes sense.I think I'm missing something big, but I'm having troubleswith mutexes(using in a parallel foreach loop somewhere else); Why do thetrylocksreturn true shouldn't they return false because the mutex isalreadylocked?The documentation says that Mutex is a recursive lock, meaning that the holder of the lock can lock it even further. :) There is an internal reference count so that the lock must be unlocked the equal number of times that it has been locked.Okay, so when doing something like this Mutex hashlock; void tdigest(string path) { MD5Digest thasher = new MD5Digest; thasher.put(read(path)); //read the path in to the MD5 API hashlock.lock(); hashkey[path] = thasher.finish(); hashlock.unlock(); } void main() { hashlock = new Mutex(); ... other stuff foreach(string s ; tp.parallel(array of strings)) { tdigest(s); } ... even more stuff } it will fail because the parallel foreach uses the main thread is being used which does some funky stuff? I'm trying to figure out how to implement this (for reference I'm just trying to create a big hash map of files and their md5's)I don't think this is a phobos bug, I'm on OSX using dmd 2.065 import core.sync.mutex; import std.stdio; void main() { Mutex m = new Mutex; m.lock(); writefln("%s", m.tryLock()); writefln("%s", m.tryLock());The lock count is now 3. You must unlock it 3 times so that another thread can lock it.return; } produces: true true Thanks! AlexAli
Mar 03 2014
For what it's worth, you can also do: auto m = new Mutex; sycnchronized (m) { // do stuff } The synchronized block will call lock on enter and unlock on exit, even as a result of a throw.
Mar 04 2014
On Monday, 3 March 2014 at 07:38:05 UTC, Ali Çehreli wrote:The documentation says that Mutex is a recursive lock, meaning that the holder of the lock can lock it even further. :) There is an internal reference count so that the lock must be unlocked the equal number of times that it has been locked.Maybe this is because I haven't done much work with multi-threading, but this seems like a strange thing. What would be the benefits of locking a mutex more than once? It makes sense to me that a mutex should be allowed to be locked only once, and anything else trying to lock it get's held up until it has been unlocked, or a false is returned in the case of a tryLock. and this may seem like a silly question(like I said, not much multi-threading experience), but what determines the holder of a lock? Is it the thread or is it a specific function? Or something else?
Mar 05 2014
On 03/05/2014 09:49 AM, Jeremy DeHaan wrote:On Monday, 3 March 2014 at 07:38:05 UTC, Ali Çehreli wrote:Same here. :) I have learned about this concept years ago at a company that I had joined recently. I wrote a function like the following: void foo() { lock(mutex); // ... code that needs to be protected by a lock ... unlock(mutex); } The problem was, foo() could be called from different contexts, some of which had already locked the same mutex. I was told that I could not do that because the lock was not recursive.The documentation says that Mutex is a recursive lock, meaning that the holder of the lock can lock it even further. :) There is an internal reference count so that the lock must be unlocked the equal number of times that it has been locked.Maybe this is because I haven't done much work with multi-threading,It makes sense to me that a mutex should be allowed to be locked only once, and anything else trying to lock it get's held up until it has been unlocked,This design does not differentiate the same thread as somebody else and allows what I had tried to do above. Of course, I could have checked whether the lock was owned by me and then lock otherwise, but doing that becomes unnecessary here.and this may seem like a silly question(like I said, not much multi-threading experience), but what determines the holder of a lock? Is it the thread or is it a specific function? Or something else?I think it is the thread. Ali
Mar 05 2014
We use non-recursive locks too. The pattern is: --- bool wasMyLock=obj.isMyLock(); if(!wasMyLock)obj.lock(); ...code... if(!wasMyLock)obj.unlock(); ---
Mar 06 2014