问题描述
我正在尝试了解 Go 中的并发性.特别是,我写了这个线程不安全的程序:
I'm trying to understand concurrency in Go. In particular, I wrote this thread-unsafe program:
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
中更新时打印数字).
I recognize that I should be using channels to prevent race conditions with x
, but that's not the point here. The program prints 1
and then seems to loop forever (without printing anything more). I would expect it to print an infinite list of numbers, possibly skipping some and repeating others due to the race condition (or worse -- printing the number while it is being updated in inc_x
).
我的问题是:为什么程序只打印一行?
My question is: Why does the program only print one line?
澄清一下:我不是故意在这个玩具示例中使用频道.
Just to be clear: I'm not using channels on purpose for this toy example.
推荐答案
关于 Go 的 goroutines:
There are a few things to keep in mind about Go's goroutines:
- 它们不是 Java 或 C++ 线程意义上的线程
- goroutines 更像是 greenlets
- 系统线程的数量由环境变量
GOMAXPROCS
控制,目前我认为默认为 1.这在未来可能会改变
- the number of system threads is controlled by an environment variable
GOMAXPROCS
and defaults to 1 currently I think. This may change in the future
- select 语句 可以将控制权交还给线程
- 发送频道可以将控制权交还给线程
- 执行 IO 操作可以将控制权交还给线程
runtime.Gosched()
明确地将控制权交还给线程
您看到的行为是因为 main 函数永远不会返回给线程,而是参与了一个繁忙的循环,而且由于只有一个线程,主循环没有地方可以运行.
The behavior you are seeing is because the main function never yields back to the thread and is instead involved in a busy loop and since there is only one thread the main loop has no place to run.
这篇关于理解 goroutine的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!