On Wed, Apr 10, 2013 at 3:32 AM, Jan Mercl wrote:On Wed, Apr 10, 2013 at 12:21 AM, Gordon Klaus wrote:
You missed the key phrase "between unsynchronized goroutines". If there is
no synchronization, then a channel close cannot be guaranteed to be
observed.
I don't think so. Channel is implemented as a pointer, so the memory
model allows a variable of type channel to be seen differently by two
non syncing goroutines. But as long as those two (or any number of)
goroutines already have the same pointer to the run time object
implementing a channel - it is no more possible after a channel close
- for any goroutine which attempts to close the same channel again, to
see it as non closed.
You are probably right about the current implementation, and from a
practical standpoint this is of course important. However, the statements
I made were implementation-independent, i.e., about the language in its
purest form, as defined by the spec and memory model. It is allowed to
have an implementation (e.g., on a distributed memory architecture) in
which different goroutines have different copies of the same channel; and
in which these copies are synchronized only to satisfy the happens-before
relationships defined in the memory model: send-receive and close-receive,
but not close-close or anything else.
By extension: No non syncing goroutine can see a
sync.Mutex as unlocked after it was locked by any other non syncing
goroutine (let's assume no Unlock ever happens to make it simple).
This is true (although not by extension of the above) because otherwise the
mutex would be broken. It is guaranteed by the memory model. From
http://golang.org/ref/mem#tmp_7: "For any sync.Mutex or sync.RWMutex
variable l and n < m, call n of l.Unlock() happens before call m of
l.Lock() returns." So if there is no call to l.Unlock(), then only the
first call to l.Lock() can return; i.e., subsequent calls to l.Lock() will
"see" that it is locked.
Channels (and eg. mutexes) are intrinsically safe for concurrent
access - the variables (arguments, pointers to) are not - if being
updated by a non syncing goroutine.
Channel operations are safe, yes. But that doesn't mean they have to be
synchronized in all cases. For example, channel sends from multiple
goroutines certainly don't have to synchronize with each other -- what
matters is that a receive synchronizes with a send.
IOW: The memory model domain covers _values_ of variables and
arguments (and things possibly pointed to by them), not necessarily
the (internal, opaque) _state_ of run time objects.
You're right. The language makes no guarantees about the internal state of
runtime objects, only their observable behavior. This means our discussion
of "seeing a lock as unlocked" or "seeing a channel as closed" doesn't
always strictly make sense, or it is implementation-dependent. It makes
more sense to discuss the observable order and effect of operations. And
when it comes to multiple channel closes on unsynchronized goroutines,
there is nothing to say about their guaranteed observable order or effect
on each other except with respect to a particular implementation.
-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+unsubscribe@googlegroups.com.
For more options, visit
https://groups.google.com/groups/opt_out.