首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >golang中的goroutine one进程错误

golang中的goroutine one进程错误
EN

Stack Overflow用户
提问于 2017-01-06 14:55:24
回答 2查看 367关注 0票数 3

我在学习关于高朗的知识。

在golang中,有一个概念,叫做goroutine。我写了一个示例代码。

代码语言:javascript
复制
package main

import (
    "fmt"
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(1) // cpu core를 하나만 사용하도록 해 놓음

    s := "test string"

    for i := 0; i < 100; i++ {
        go func(n int) {
            fmt.Println(s, n)
        }(i)
    }

    fmt.Scanln()
}

如果解释代码并运行,您将看到第一个打印数据是

测试字符串99

我不知道为什么结果是这样。有没有人帮我?

EN

回答 2

Stack Overflow用户

发布于 2017-01-06 15:10:01

这是因为这一行:

代码语言:javascript
复制
runtime.GOMAXPROCS(1)

因为goroutine是并发执行代码的一种方式,所以您在循环中创建的所有goroutine都必须等待proc。

由于您只有一个,并且它正忙于执行循环,因此您将有一堆goroutine等待。

当循环结束时,proc有时间执行第一个goroutine,也就是最后创建的goroutine,然后逐个对堆栈执行相同的操作,但这次是按顺序执行。

试着使用2个proc,看看会发生什么。

请记住,当您在并发工作时,代码的执行顺序是不能保证的,正如已经在注释中提到的那样。

这里你有一个序列,仅仅因为你只有一个进程。

如果您的目的是让项目按顺序处理,甚至以并发的方式处理,则应该使用通道。

让我展示一个完成这项工作的代码示例:

package main

代码语言:javascript
复制
import (
    "fmt"
    "runtime"
)

func printNumbers(text string, ns chan int) {
    for n := range ns {
        fmt.Println(text, n)
    }
}

func main() {
    runtime.GOMAXPROCS(1) // cpu core를 하나만 사용하도록 해 놓음

    s := "test string"

    numbers := make(chan int)

    go printNumbers(s, numbers)

    go func() {
        for i := 0; i < 100; i++ {
            numbers <- i
        }
        close(numbers)
    }()

    fmt.Scanln()
}

正如你所看到的,这只是你的的一个新版本,但是如果你执行了,你应该会得到正确的序列。

主要的变化是现在有两个goroutine,一个用于打印,一个用于循环。

两个goroutine对话通过一个int通道。

当程序开始第一个goroutin调用函数printNumbers时,该函数将等待,直到某些内容被写入通道。

然后开始第二次输出,将整数逐个写入通道。

一旦for结束,因为您只有1个进程,当通道内有项目时,printNumbers函数将再次启动。

它会循环,直到它结束项目。

当然,这里有两个循环,但你无法避免它。

因此,现在试着按您希望的方式执行进程,看看会发生什么。

票数 3
EN

Stack Overflow用户

发布于 2017-01-06 15:57:24

你的问题很好,答案基本上是内部运行时Go Scheduler是如何工作的,但正如Mario Santini所说的那样,执行的顺序是不能保证的。

在我有限的语言中,我可以告诉你Go Scheduler取决于内部使用的进程调度算法https://en.wikipedia.org/wiki/Scheduling_(computing),基于这一点,它将决定执行多少时间和每个goroutine请求运行的顺序,它还将根据需要为您创建操作系统线程,在您的情况下,您仅将其限制为1,因此它将根本不是parallel,所以很明显,最后一个goroutine足够幸运地将其作为第一个goroutine运行。

我给你留下了一些更好的解释的链接:

https://www.quora.com/How-does-the-golang-scheduler-work http://www.sarathlakshman.com/2016/06/15/pitfall-of-golang-scheduler http://www.slideshare.net/matthewrdale/demystifying-the-go-scheduler

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41500528

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档