How could we emulate condition variables using Go channels only?

336 views
Skip to first unread message

Rochus Keller

unread,
Jan 12, 2024, 1:58:03 PM1/12/24
to golang-nuts

Here is the full question with examples (though meanwhile closed as usual in recent times on stackoverflow, so answer here please): https://stackoverflow.com/questions/77802102/mutex-and-condition-variables-in-go-without-using-the-sync-package

This is a conceptual question based on the duality of monitors and message passing. My goal is to see and be able to experiment with a correct and complete example of a mutex with condition variables in Go which only use Go channels for implementation, as a proof of concept. Only then we can discuss how far it makes sense from an engineering standpoint.

Jan Mercl

unread,
Jan 12, 2024, 2:17:57 PM1/12/24
to Rochus Keller, golang-nuts
On Fri, Jan 12, 2024 at 7:57 PM Rochus Keller <rochus...@gmail.com> wrote:

> Here is the full question with examples (though meanwhile closed as usual in recent times on stackoverflow, so answer here please): https://stackoverflow.com/questions/77802102/mutex-and-condition-variables-in-go-without-using-the-sync-package
>
> This is a conceptual question based on the duality of monitors and message passing. My goal is to see and be able to experiment with a correct and complete example of a mutex with condition variables in Go which only use Go channels for implementation, as a proof of concept. Only then we can discuss how far it makes sense from an engineering standpoint.
>

Something like this? https://go.dev/play/p/_H3kFjprAGG

Rochus Keller

unread,
Jan 12, 2024, 2:48:09 PM1/12/24
to golang-nuts
> Something like this? https://go.dev/play/p/_H3kFjprAGG

No, sorry. The goal is to emulate a full monitor just with channels, as demonstrated in the referenced text (see the Stack example). The Mutex is likely correct, but the Signal has yet to pass the scrutinity of the folks here.

Bryan C. Mills

unread,
Jan 17, 2024, 5:38:18 PM1/17/24
to golang-nuts
Perhaps something like this:

Disclaimer: not yet tested, probably contains bugs.
Also, I strongly _disrecommend_ the use of condition variables, because they're too bug-prone. 🙃

Bryan C. Mills

unread,
Jan 18, 2024, 11:23:45 AM1/18/24
to golang-nuts

Jason E. Aten

unread,
Jan 21, 2024, 11:08:35 AM1/21/24
to golang-nuts
I like this question, as a fun puzzle to solve. Bryan's approach is similar to how I am thinking about it.

Reading his code (https://go.dev/play/p/BpLBYsSSqn2?v=gotip), however, I think there are some issues:

1) What if there are two simultaneous calls to Broadcast that end up closing the
same channel (on line 46) twice?  A panic would ensue due to the double close. (I've long
felt that this was a poor choice in Go's channel design, a double close should really be fine -- the
current design means that you almost always have to protect a close() 
with a separate mutex, and check if the close has already happened first).

2) What Signal and Broadcast are called at the same time, and the lines are interleaved
36, 45, 46, 38: you would get a panic from trying to send on a closed channel, right?

Jason E. Aten

unread,
Jan 21, 2024, 11:49:12 AM1/21/24
to golang-nuts
Update: nope, I was wrong. Those two scenarios cannot happen. Because reading the one
value in cc.ready acts as a mutex already.

Reply all
Reply to author
Forward
0 new messages