Live data from Hacker News

What could Go wrong with a mutex

evilmartians.com

11–20 of 59 posts

Re: What could Go wrong with a mutex

#11
post #9
post #8

Earlier quoted context omitted.

Is there a language where deadlocks are not possible ?

Avoiding deadlocks is easy if you're lockfree (or otherwise non-blocking), the interesting bit is being data-race free: https://www.ponylang.io/discover/#what-makes-pony-different

Now that's something remarkable about a language. Definitely going to check out Pony now.

Re: What could Go wrong with a mutex

#12
post #8
post #4

People talk about the lack of generics et al as being Go's downfall but personally what I've found to be the biggest annoyance is the very thing Go boasts to be good at: writing bug/race free multi-threaded code. Channels are vastly oversold given their actual suitability and worse still, add their own classes of race conditions (deadlocks) so you often fallback to using mutexes for those, hopefully rare, occasions y…

Is there a language where deadlocks are not possible ?

None that I've used. But some are better than others for mitigating such scenarios. Go is pretty poor in that regard. I don't think it helped that the early releases were single threaded by default -- the argument being to help with developer onboarding. But really pain points like these need to be flushed out while the language was still being defined rather than hidden away.

Re: What could Go wrong with a mutex

#13
post #4

People talk about the lack of generics et al as being Go's downfall but personally what I've found to be the biggest annoyance is the very thing Go boasts to be good at: writing bug/race free multi-threaded code. Channels are vastly oversold given their actual suitability and worse still, add their own classes of race conditions (deadlocks) so you often fallback to using mutexes for those, hopefully rare, occasions y…

Yes, I fully agree. The basics and primitives are very simple and easy, but actually using those to make useful packages is far harder than it might seem at first glance.

Goroutines and channels are not bad at all, but I feel there's some part missing to use them effectively without too much headaches. I've often found sync.WaitGroup and mutexes far more useful than channels.

Actually, I wrote an entire article about this, discussed here: https://news.ycombinator.com/item?id=26220693

Re: What could Go wrong with a mutex

#14
post #4

People talk about the lack of generics et al as being Go's downfall but personally what I've found to be the biggest annoyance is the very thing Go boasts to be good at: writing bug/race free multi-threaded code. Channels are vastly oversold given their actual suitability and worse still, add their own classes of race conditions (deadlocks) so you often fallback to using mutexes for those, hopefully rare, occasions y…

Generics could for instance have helped implement a mutex that disallows access to the memory that needs to be synchronized without locking it first. This of course wouldn't have helped here, as the root cause was holding on to the mutex for too long.

I was under the impression that Go had first party tooling for deadlock checking, something called threadanalyzer if I recall correctly.

Re: What could Go wrong with a mutex

#15
post #10

I would zoom in on the actual fix: shrinking the size of the critical section. When you use defer to release the lock, the entirety of your function becomes the critical section. If you add another bit of code that needs the same lock, your program goes boom. I've hit this same issue a few times when I write a new, naive HTTP handler function that needs concurrent map access, then throw apachebench at it before I com…

I think deferring unlocks should be more openly described as an anti-pattern. I do appreciate the convenience of defer generally speaking but it has two problems that specifically hinder effective use of mutexes:

1. it allows you to roll up additional code that doesn't need to be inside the mutex, thus keeping other threads waiting longer for an unlock

2. Benchmarks have shown[1][2] that using defer is actually more expensive than not using defer and simply having the unlock sit just before your return call(s). I get defer produces more readable and safer code, however when you have a locking function, your are concerned with unlocking quickly. So defer directly causes complications here that, in my opinion, outweighs any benefits you get with regards to readability.

Sadly a lot of mutex examples specifically use defer without addressing any of the risks of doing so. such as GoByExample.com[3]

[1] https://gist.github.com/janisz/ce19a7fa94cbc99e2835a4421ccfc...

[2] https://medium.com/i0exception/runtime-overhead-of-using-def...

[3] https://gobyexample.com/mutexes

Re: What could Go wrong with a mutex

#16
post #9
post #8

Earlier quoted context omitted.

Is there a language where deadlocks are not possible ?

Avoiding deadlocks is easy if you're lockfree (or otherwise non-blocking), the interesting bit is being data-race free: https://www.ponylang.io/discover/#what-makes-pony-different

> Avoiding deadlocks is easy if you're lockfree (or otherwise non-blocking)

Only if you’re also concurrency free.

If you can still have two actors waiting on one another, you’re letter-of-the-law deadlock-free, but your program is still in effect deadlocked.

> the interesting bit is being data-race free:

Data race freedom is much weaker (and easier) than deadlock freedom, or race condition freedom.

Safe rust is free of data races for instance. But still subject to deadlocks, and other race conditions.

Re: What could Go wrong with a mutex

#17
post #15
post #10

I would zoom in on the actual fix: shrinking the size of the critical section. When you use defer to release the lock, the entirety of your function becomes the critical section. If you add another bit of code that needs the same lock, your program goes boom. I've hit this same issue a few times when I write a new, naive HTTP handler function that needs concurrent map access, then throw apachebench at it before I com…

I think deferring unlocks should be more openly described as an anti-pattern. I do appreciate the convenience of defer generally speaking but it has two problems that specifically hinder effective use of mutexes: 1. it allows you to roll up additional code that doesn't need to be inside the mutex, thus keeping other threads waiting longer for an unlock 2. Benchmarks have shown[1][2] that using defer is actually more…

> So defer directly causes complications here that, in my opinion, outweighs any benefits you get with regards to readability.

The primary advantage of defer is not readability, it’s safety, in the presence of both panics and code evolving.

Re: What could Go wrong with a mutex

#18
post #15

Earlier quoted context omitted.

I think deferring unlocks should be more openly described as an anti-pattern. I do appreciate the convenience of defer generally speaking but it has two problems that specifically hinder effective use of mutexes: 1. it allows you to roll up additional code that doesn't need to be inside the mutex, thus keeping other threads waiting longer for an unlock 2. Benchmarks have shown[1][2] that using defer is actually more…

> So defer directly causes complications here that, in my opinion, outweighs any benefits you get with regards to readability. The primary advantage of defer is not readability, it’s safety, in the presence of both panics and code evolving.

Yes, I agree and covered your point regarding safety in literally the sentence before that which you quoted :)

Re: What could Go wrong with a mutex

#19
post #18

Earlier quoted context omitted.

> So defer directly causes complications here that, in my opinion, outweighs any benefits you get with regards to readability. The primary advantage of defer is not readability, it’s safety, in the presence of both panics and code evolving.

Yes, I agree and covered your point regarding safety in literally the sentence before that which you quoted :)

You didn't, really. You mentioned it in passing then completely ignored the issue without actually addressing how to handle the issue of locking in face of go's lack of panic safety, or human errors.

Re: What could Go wrong with a mutex

#20
post #4

People talk about the lack of generics et al as being Go's downfall but personally what I've found to be the biggest annoyance is the very thing Go boasts to be good at: writing bug/race free multi-threaded code. Channels are vastly oversold given their actual suitability and worse still, add their own classes of race conditions (deadlocks) so you often fallback to using mutexes for those, hopefully rare, occasions y…

I don't think I've ever seen anyone saying that Go is supposed to be good at writing bug/race-free multi-threaded code.
Post reply on HN