一些常见的并发编程错误

2024年 7月 18日 72.3k 0

一些常见的并发编程错误-1

Go 是一个内置支持并发编程的语言。借助使用 go 关键字去创建 协程 goroutine (轻量级线程)和在 Go 中提供的 使用 信道 和 其它的并发 同步方法,使得并发编程变得很容易、很灵活和很有趣。

另一方面,Go 并不会阻止一些因 Go 程序员粗心大意或者缺乏经验而造成的并发编程错误。在本文的下面部分将展示一些在 Go 编程中常见的并发编程错误,以帮助 Go 程序员们避免再犯类似的错误。

需要同步的时候没有同步

代码行或许 不是按出现的顺序运行的。

在下面的程序中有两个错误。

  • 第一,在 main 协程中读取 b 和在新的 协程 中写入 b 可能导致数据争用。
  • 第二,条件 b == true 并不能保证在 main 协程 中的 a != nil。在新的协程中编译器和 CPU 可能会通过 重排序指令 进行优化,因此,在运行时 b 赋值可能发生在 a 赋值之前,在 main 协程 中当 a 被修改后,它将会让部分 a 一直保持为 nil
package main

import (
    "time"
    "runtime"
)

func main() {
    var a []int // nil
    var b bool  // false

    // a new goroutine
    go func () {
        a = make([]int, 3)
        b = true // write b
    }()

    for !b { // read b
        time.Sleep(time.Second)
        runtime.Gosched()
    }
    a[0], a[1], a[2] = 0, 1, 2 // might panic
}

上面的程序或者在一台计算机上运行的很好,但是在另一台上可能会引发异常。或者它可能运行了 N 次都很好,但是可能在第 (N+1) 次引发了异常。

我们将使用 sync 标准包中提供的信道或者同步方法去确保内存中的顺序。例如,

package main

func main() {
var a []int = nil
c := make(chan struct{})

// a new goroutine
go func () {
a = make([]int, 3)
c

相关文章

Linux 命令行的聊天工具 CenterIM
Linux 桌面年仍未到来 但 Linux 移动之年已到来
12 个在线学习 Linux 技能网站
Linux Mint : 会是另一个新的 Ubuntu 吗?
W3Conf 开发者大会将于下周召开
Ubuntu 10.04 ARM 处理器上网本版本结束服务期

发布评论