Hi,all. I'm reading the source code of sync package recently.
Here is a code snippet in sync/mutex.go. // src/sync/mutex.go type Mutex struct { state int32 sema uint32 } func (m *Mutex) lockSlow() { var waitStartTime int64 starving := false awoke := false iter := 0 old := m.state // Here!!! not use atomic.LoadInt32() for { // Don't spin in starvation mode, ownership is handed off to waiters // so we won't be able to acquire the mutex anyway. if old&(mutexLocked|mutexStarving) == mutexLocked && runtime_canSpin(iter) { // Active spinning makes sense. // Try to set mutexWoken flag to inform Unlock // to not wake other blocked goroutines. if !awoke && old&mutexWoken == 0 && old>>mutexWaiterShift != 0 && atomic.CompareAndSwapInt32(&m.state, old, old|mutexWoken) { awoke = true } // ... old = m.state // And here!!! not use atomic.LoadInt32() continue } // ... } // ... } You can see full context in link1 <https://github.com/golang/go/blob/master/src/sync/mutex.go#L113> and link2 <https://github.com/golang/go/blob/master/src/sync/mutex.go#L127> I have read The Go Memory Model <https://go.dev/ref/mem>, It says "Reads and writes of values larger than a single machine word behave as multiple machine-word-sized operations in an unspecified order." Althought it is usually 32 or 64 bits on modern machine,I think if you want a operator is atomic,you should use atomic.LoadXXX() explicitly. I think a ordinary read operator like old := m.state in concurrent environment is not safe,it may read a unexpected value. I wonder whether the oridinary read operation is right? Could you help me? Thanks in advance. I'm very sorry to disturb you... -- 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. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/31c5c265-a125-48ad-bbdc-5cb5f0fd7a8en%40googlegroups.com.