I like to think of a channel as a concurrent messaging queue. You can do all sorts of things with such constructs, including implementing mutual exclusion constructs, but that doesn't mean that one is the other.
Your playground example is a bit weird and very prone to various kinds of race conditions that indicate that it may not be doing what you expect. At a high level, your program loops 10 times. Each loop iteration spawns a new concurrent process that attempts to read a value off of a channel three times. Each iteration of the main loop writes exactly one value into the channel. As a concurrent queue, writes to the channel can be thought of as appending an element, reads can be thought of as removing an element from the front. Which goroutine will read any individual value is not deterministic. Since you're only sending 11 values over the channel, but spawn 10 goroutines that each want to read 3 values, you have at best 6 goroutines still waiting for data to be sent (and at worse, all 10) at the time the program exits. I would also point out that this is not evidence of mutual exclusion. Consider a case where the work performed after the channel read exceeds the time it takes for the outer loop to write a new value to the channel. In that case, another goroutine waiting on the channel would begin executing. This is not mutual exclusion. In this regard, the example you've posted is more like a condition variable or monitor than it is like a mutex. Also note that in your second playground post, you're spawning 12 goroutines, so I'm not sure what "goroutine1" and "goroutine2" are supposed to mean. Kind regards, --dho Op zo 17 mrt. 2019 om 13:07 schreef Louki Sumirniy <louki.sumirniy.stal...@gmail.com>: > > https://play.golang.org/p/13GNgAyEcYv > > I think this demonstrates how it works quite well, it appears that threads > stick to channels, routine 0 always sends first and 1 always receives, and > this makes sense as this is the order of their invocation. I could make more > parallel threads but clearly this works as a mutex and only one thread gets > access to the channel per send/receive (one per side). > > On Sunday, 17 March 2019 14:55:58 UTC+1, Jan Mercl wrote: >> >> On Sun, Mar 17, 2019 at 1:04 PM Louki Sumirniy <louki.sumir...@gmail.com> >> wrote: >> >> > My understanding of channels is they basically create exclusion by control >> > of the path of execution, instead of using callbacks, or they bottleneck >> > via the cpu thread which is the reader and writer of this shared data >> > anyway. >> >> The language specification never mentions CPU threads. Reasoning about the >> language semantics in terms of CPU threads is not applicable. >> >> Threads are mentioned twice in the Memory Model document. In both cases I >> think it's a mistake and we should s/threads/goroutines/ without loss of >> correctness. >> >> Channel communication establish happen-before relations (see Memory Model). >> I see nothing equivalent directly to a critical section in that behavior, at >> least as far as when observed from outside. It was mentioned before that >> it's possible to _construct a mutex_ using a channel. I dont think that >> implies channel _is a mutex_ from the perspective of a program performing >> channel communication. The particular channel usage pattern just has the >> same semantics as a mutex. >> >> -- >> >> -j > > -- > 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+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.