Ah yes, probably 'loop1' 'loop2' would be more accurate names. Yes the number of each routine is in that 'i' variable, those other labels are just to denote the position within the loops and before and after sending and the state of the truthstate variable that is only accessed inside the goroutine.
Yes, this is a very artificial example because the triggering of send operations is what puts all the goroutines into action. The serial nature of the outer part in the main means that this means only the sequentially sent and received messages will mostly always come out in the same order as they go in (I'd say, pretty much always, except maybe if there was a lot of heavy competition for goroutines compared to the supply of CPU threads. If in an event driven structure with multiple workers that need to share and notify state through state variables, one goroutine might send and then another runs and receives. So, maybe this means I need to have a little more code in the goroutine after it empties the channel that verifies by reading that state hasn't changed and starts again if it has. So, ok, I guess the topic is kinda wrongly labeled. I am just looking for a way to queue read and write access to a couple of variables, and order didn't matter just that one read or write is happening at any given moment. So to be a complete example I would need randomised and deliberately congested spawing of threads competing to push to the channel, and inside the loop it should have a boolean or maybe 'last modified' stamp that after it empties the channel it checks that isn't changed and if it is restarts. But yes, that could still get into a deadlock if somehow two routines get into a perfect rhythm with each other. I will have to think more about this, the code I am trying to fix I suppose it would help if I understood its logic flow before I just try and prevent contention by changing the flow if this is possible. On Sunday, 17 March 2019 21:59:30 UTC+1, Devon H. O'Dell wrote: > > 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.sumir...@gmail.com <javascript:>>: > > > > 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...@googlegroups.com <javascript:>. > > 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.