跳转到内容
View in the app

A better way to browse. Learn more.

彼岸论坛

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
欢迎抵达彼岸 彼岸花开 此处谁在 -彼岸论坛

[Go 编程语言] 请教一个竞争问题

发表于

go memory model 中说:

...each read of a single-word-sized or sub-word-sized memory location must observe a value actually written to that location (perhaps by a concurrent executing goroutine) and not yet overwritten.

这句话是否可以理解为读一个字长以下的数据, 总是会读到某一次写入的数据, 而不会读到某个中间状态?

如果上述理解是正确的, 那么对于下面的程序:

package main

import (
	"fmt"
	"sync"
	"time"
)

type A struct {
	data string
}

func main() {
	a := &A{data: "b"}
    
	go func() {
		for {
			if a.data == "a" {
				a = &A{data: "b"}
			} else {
				a = &A{data: "a"}
			}
		}
	}()

	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			for i := 0; i < 100000; i++ {
				// 复制 a 的指针, aa 在接下来的使用中应该指向同一个 A
				aa := a
				if aa.data != "a" && aa.data != "b" {
					panic(aa.data)
				}
			}
			wg.Done()
		}()
	}

	start := time.Now()
	wg.Wait()
	fmt.Println(time.Since(start))
}

由于指针 *A 是一个字长, 那么读取变量 a 总是会读到某一个 A 地址, 所以 panic 不会发生, 但实际上会出现:

panic: 

goroutine 6 [running]:
main.main.func2()
	/Users/a/test/test.go:44 +0xa0
created by main.main in goroutine 1
	/Users/a/test/test.go:40 +0x44
exit status 2

这是为什么?

Featured Replies

No posts to show

创建帐户或登录来提出意见

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.