Check if sync.Mutex is locked

9,249 views
Skip to first unread message

Dump Hole

unread,
Feb 2, 2015, 6:08:40 PM2/2/15
to golan...@googlegroups.com
Is there a way to check if a sync.Mutex is currently locked?  I am processing a resource, and I want to check if there's already a goroutine that's processing it.  If there is, then this goroutine should wait until the processed resource is available, rather than repeat the process.  So the code would look like this:

if mutex.TryLock() {
    defer mutex.Unlock()
    waitGroup.Add(1)
    defer waitGroup.Done()
   
    // process resource
} else {
    waitGroup.Wait()

    // consume processed resource
}

If I were to do this with just Lock() and Unlock(), Lock() will block the goroutine, and after it acquires the lock, I have to recheck if the processed resource is available before processing it.  This is very similar to concurrency programming in languages like Java.

Péter Szilágyi

unread,
Feb 2, 2015, 6:13:24 PM2/2/15
to Dump Hole, golang-nuts
There would be a race condition :P

P1: TryLock -> obtains the lock
P2: TryLock -> already locked, skip
P2: Wait -> nothing's in the waitgroup
P2: Consume uninitialized resource !!!
P1: Add -> too late...

There is nothing useful you could gain with checking if a mutex is locked or not, because by the time you get to process it, it could be already irrelevant. It's a very dangerous thing to do.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Nigel Tao

unread,
Feb 2, 2015, 6:13:26 PM2/2/15
to Dump Hole, golang-nuts
On Tue, Feb 3, 2015 at 10:08 AM, Dump Hole <dumpst...@gmail.com> wrote:
> Is there a way to check if a sync.Mutex is currently locked?

No. https://groups.google.com/forum/#!msg/golang-nuts/OM37bQ41n3Q/wtZgT5wwtUcJ

Ian Lance Taylor

unread,
Feb 2, 2015, 6:18:20 PM2/2/15
to Dump Hole, golang-nuts
On Mon, Feb 2, 2015 at 3:08 PM, Dump Hole <dumpst...@gmail.com> wrote:
>
> Is there a way to check if a sync.Mutex is currently locked?

No. See http://golang.org/issue/6123 .

Ian

Kevin Malachowski

unread,
Feb 2, 2015, 6:55:54 PM2/2/15
to golan...@googlegroups.com
You should look into sync.Once, it might do what you want.

Edward Muller

unread,
Feb 2, 2015, 7:01:04 PM2/2/15
to Dump Hole, golang-nuts
Pass the resource on a channel and it will be picked up by a single go-routine receiving from that channel. Once done processing, pass it back onto that or another channel (depending on what's next)?

But, TBH a better/more concrete explanation of what your doing would probably help people on this list to given more highly qualified answers. 

On Mon, Feb 2, 2015 at 3:08 PM, Dump Hole <dumpst...@gmail.com> wrote:

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Edward Muller
@freeformz
Message has been deleted

Edward Muller

unread,
Feb 2, 2015, 11:26:11 PM2/2/15
to Dump Hole, golang-nuts
* sync.Once if you want to do something once and only once.

* sync.Cond if you need multiple goroutines to Wait() for a condition to be true (Although I personally prefer using channels, but readability and use cases can make sync.Cond more attractive).

* channels for everything else.
--
Edward Muller
@freeformz

Kevin Malachowski

unread,
Feb 3, 2015, 2:34:58 AM2/3/15
to Edward Muller, Dump Hole, golang-nuts
On Mon, Feb 2, 2015 at 11:25 PM, Edward Muller <edwa...@interlix.com> wrote:
* sync.Once if you want to do something once and only once.
In addition, concurrent callers to Do will wait until the function (which is running on some other goroutine) returns. Unless you want to wait for the result of the function you shouldn't use it, really. I often use this for simple lazy initialization when the data is read-only after init.


* sync.Cond if you need multiple goroutines to Wait() for a condition to be true (Although I personally prefer using channels, but readability and use cases can make sync.Cond more attractive).

Conds are useful if you need to hold a mutex to access the data after it is initialized. It's also better for a Broadcast message if you need to do it more than once. You can close a channel as a broadcast but then it is closed forever (which is either okay or not okay depending on the situation).

You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/GeHbpo6AtTc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.

DH

unread,
Feb 3, 2015, 3:08:21 AM2/3/15
to golang-nuts
@EdwardMuller

Well that's what I am trying to do.  There's a resource that needs to be processed on-demand.  So I a spin up a goroutine to do that.  However, if during the process there's another request that's requesting for the same resource, I don't really want to spin another goroutine to process it.  I need to do a "look-there-is-a-thread-running-that's-handling-this-already-so-you-just-wait-until-it's-done" activity.

If I were to do this:

if resource.NotAvailable() {
    go func() {
        mutex.Lock()
        defer mutex.Unlock()
        // process resource
    }()
}

Then the second request will re-process the resource.  So my current solution is:

if resource.NotAvailable() {
    go func() {
        mutex.Lock()
        defer mutex.Unlock()

        // do another check
        if resource.Available() {
            // return
        }

        // process resource
    }
}

This is what I would've done in Java/C++.  Since go is excellent in concurrency, it just seems a little "unlike-go" when I write my code like that.

aro...@gmail.com

unread,
Feb 3, 2015, 3:24:48 AM2/3/15
to golan...@googlegroups.com, andrewc...@gmail.com
Seems like you want to limit each resource to at most one processing.  Something like this?  http://play.golang.org/p/gifaJNTNRy


More info would be helpful.

On Monday, February 2, 2015 at 4:53:30 PM UTC-8, andrewc...@gmail.com wrote:
Use http://golang.org/pkg/sync/#Cond. This is what its desired for.

Dmitry Vyukov

unread,
Feb 3, 2015, 3:26:10 AM2/3/15
to DH, golang-nuts
There is a nice example of implementation in encoding/json:typeEncoder
https://go.googlesource.com/go/+/master/src/encoding/json/encode.go

Alex Zylman

unread,
Feb 3, 2015, 7:45:30 PM2/3/15
to golan...@googlegroups.com, dumpst...@gmail.com
I picked up this snippet in this group a while back, that sounds like it does what you want:


Basically it takes a function and returns a function that blocks until there's a result and then returns the result, but will only ever compute the result once. This version assumes that the only result is an error or nil, but it's probably not that hard to extend to support other results (assuming you're fine with writing functions specific for this use case).

Edward Muller

unread,
Feb 3, 2015, 8:17:07 PM2/3/15
to DH, golang-nuts
Here is a somewhat contrived example using once: https://play.golang.org/p/Nsy2CB6och

This assumes you already have a "resource".

If not you probably want a map and a lock, much like what Dmitry pointed to in json:typeEncoder

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Edward Muller
@freeformz

Nick Craig-Wood

unread,
Feb 4, 2015, 5:00:14 AM2/4/15
to golan...@googlegroups.com
I'll second that. sync.Cond is a little tricky to use, but it does
exactly this really well.

On 03/02/15 00:53, andrewc...@gmail.com wrote:
> Use http://golang.org/pkg/sync/#Cond. This is what its desired for.
>
> On Tuesday, February 3, 2015 at 12:08:40 PM UTC+13, Dump Hole wrote:
>
> --
> You received this message because you are subscribed to the Google
> Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to golang-nuts...@googlegroups.com
> <mailto:golang-nuts...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.


--
Nick Craig-Wood <ni...@craig-wood.com> -- http://www.craig-wood.com/nick

roger peppe

unread,
Feb 4, 2015, 5:20:28 AM2/4/15
to DH, golang-nuts
Check out http://godoc.org/camlistore.org/pkg/singleflight which
implements pretty much exactly what you've just described.
Reply all
Reply to author
Forward
0 new messages