一尘不染

了解goroutines

go

我试图了解Go中的并发性。特别是,我编写了以下线程不安全程序:

package main

import "fmt"

var x = 1

func inc_x() { //test
  for {
    x += 1
  }
}

func main() {
  go inc_x()
  for {
    fmt.Println(x)
  }
}

我认识到我应该使用渠道来防止与发生竞争x,但这不是重点。程序打印1,然后似乎永远循环(不再打印任何内容)。我希望它能打印出无限的数字列表,可能由于竞态条件而跳过某些数字并重复其他数字(或更糟的是,在更新数字时打印数字inc_x)。

我的问题是:为什么程序只打印一行?

只是要清楚一点:对于这个玩具示例,我不是故意使用渠道。


阅读 228

收藏
2020-07-02

共1个答案

一尘不染

关于Go的 goroutine,
有几点需要牢记:

  1. 它们不是Java或C ++线程的意义上的线程
  2. go运行时在 系统线程 之间多路复用goroutines __
    • 系统线程数由环境变量控制,GOMAXPROCS我认为当前默认为1。将来可能会改变
  3. goroutines返回当前线程的方式由几种不同的结构控制
    • select语句 可以产生控制回线
    • 通道 上发送可以将控制权交还给线程
    • 进行IO操作可以将控制权交还给线程
    • runtime.Gosched() 明确地将控制权交还给线程

您看到的行为是因为main函数从不屈服于线程,而是参与了繁忙的循环,并且由于只有一个线程,因此main循环无处运行。

2020-07-02