刚刚学习了golang GMP模型,现在我了解了goroutines、操作系统线程和golang上下文/处理器如何相互协作。但我还是不明白什么时候会产生M和P?
例如,我有一个测试代码来在数据库上运行一些操作,并且有两个测试用例(两批 goroutine):
func Test_GMP(t *testing.T) { for _ = range []struct { name string }{ {"first batch"}, {"second batch"}, } { goroutineSize := 50 done := make(chan error, goroutineSize) for i := 0; i < goroutineSize; i++ { go func() { // do some databases operations... // each goroutine should be blocked here for some time... // propogate the result done <- nil }() } for i := 0; i < goroutineSize; i++ { select { case err := <-done: assert.NoError(t, err) case <-time.After(10 * time.Second): t.Fatal("timeout waiting for txFunc goroutine") } } close(done) } }
以我的理解,如果M是在需要时创建的。在第一批 goroutine 中,将创建 8 个(我计算机上的虚拟核心数量)操作系统线程,第二批将仅重用这 8 个操作系统线程,而不创建新线程。这是正确的吗?
如果您可以提供有关此主题的更多材料或博客,我们将不胜感激。
仅当您的进程没有阻塞或没有任何系统调用时,M 才可重用。在您的情况下,您的 go func()
中有阻塞任务。因此,M 的数量不会限制为 8(我计算机上的虚拟核心数)。第一批将阻塞并从 P 中删除,并等待阻塞进程完成,同时新的 M 创建与 P 的关联。
请参阅以下内容了解更多详细信息,
以上是Go调度器什么时候会创建新的M和P?的详细内容。更多信息请关注PHP中文网其他相关文章!