gpt4 book ai didi

go - 一段时间后停止协程

转载 作者:行者123 更新时间:2023-12-01 22:39:38 25 4
gpt4 key购买 nike

像这样在一段时间后停止 gouroutine 是否并发安全?

  • Code :(注意: 数据争用 因为 ok 在另一个 goroutine 中发生了变化):
  • package main

    import (
    "fmt"
    "time"
    )

    func main() {
    var ok byte
    time.AfterFunc(1000*time.Millisecond, func() {
    ok = 1
    })

    var i uint64
    for ok == 0 {
    i++ // CPU intensive task
    }
    fmt.Println(i) // 2_776_813_033
    }
    终端:
    go run -race .

    ==================
    WARNING: DATA RACE
    Write at 0x00c000132010 by goroutine 8:
    main.main.func1()
    ./main.go:11 +0x46

    Previous read at 0x00c000132010 by main goroutine:
    main.main()
    ./main.go:15 +0xf4

    Goroutine 8 (running) created at:
    time.goFunc()
    go/src/time/sleep.go:180 +0x51
    ==================
    80849692
    Found 1 data race(s)
  • Code ( 数据竞争):
  • package main

    import (
    "fmt"
    "sync/atomic"
    "time"
    )

    func main() {
    var ok int32
    time.AfterFunc(1000*time.Millisecond, func() {
    atomic.StoreInt32(&ok, 1)
    })

    var i uint64
    for atomic.LoadInt32(&ok) == 0 {
    i++ // CPU intensive task
    }
    fmt.Println(i) // 2_835_935_488
    }

    终端:
    go run -race .

    31934042

    最佳答案

    即使 ok 也不能保证忙等待循环会终止。设置为 false通过另一个 goroutine。 ok的设置和读取过程中没有显式同步,因此不能保证主 goroutine 看到对其所做的更改。换句话说,没有办法在两个 goroutine 之间建立发生前的关系。

    https://golang.org/ref/mem

    代码的第二个版本是安全的,尽管 Go 内存模型中没有针对 ok 进行说明。 ,但它并不安全,因为如此紧密的循环可能不允许其他 goroutine 执行。原子读/写具有发生之前关系所必需的内存屏障。您应该使用同步原语之一(互斥体、 channel )来保证这一点。

    关于go - 一段时间后停止协程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59514634/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com