为了账号安全,请及时绑定邮箱和手机立即绑定

main 函数是否运行一个 goroutine?

main 函数是否运行一个 goroutine?

Go
慕的地8271018 2023-05-08 18:02:30
该main()函数是 goroutine 吗?例如,我看到了如下所示的崩溃堆栈跟踪,这让我想问:goroutine 1 [running]: main.binarySearch(0x0, 0x61, 0x43,0xc420043e70, 0x19, 0x19, 0x10)      /home/---/go/src/github.com/----/sumnum.go:22 +0x80 main.main()      /home/---/go/src/github.com/---/sumnum.go:13 +0xc1 exit status 2
查看完整描述

3 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

main 函数是 goroutine 吗?

不。

主要功能是一个功能。

相比之下,

goroutine是一个轻量级执行线程。

所以goroutines执行的是函数,但是goroutines不是函数,goroutines和函数之间不是一对一的关系。

然而...

main()函数在第一个(并且仅在启动时)goroutine 中执行,goroutine #1.

但是一旦该函数调用另一个函数,main goroutine 就不再执行 main 函数,而是执行其他函数。

所以很明显 goroutine 和函数是完全不同的实体。

不要将 goroutines 与函数混为一谈!!

函数和协程是完全不同的概念。而将它们视为同一事物会导致无数的困惑和问题。


查看完整回答
反对 回复 2023-05-08
?
30秒到达战场

TA贡献1828条经验 获得超6个赞

是的,主要功能作为 goroutine(主要的)运行。

goroutine 是由 Go 运行时管理的轻量级线程。 go f(x, y, z) 启动一个新的 goroutine 运行f(x, y, z)f、x、y 和 z 的评估发生在当前 goroutine中,而执行f发生在新的 goroutine 中。
Goroutines 运行在同一个地址空间,所以对共享内存的访问必须是同步的。sync 包提供了有用的原语,尽管在 Go 中你不需要太多,因为还有其他原语。

所以根据这个官方文档,这main当前的 goroutine
准确地说(字面意思)我们可以将 themain称为当前 goroutine,所以简单地说它是一个 goroutine。(注意:从字面上看,这main()是一个可以作为 goroutine 运行的函数。)


现在让我们计算使用的 goroutines 的数量runtime.NumGoroutine()

作为一个例子,让我们运行 3 个 goroutines。在线试用:

package main


import (

    "fmt"

    "runtime"

    "time"

)


func main() {

    fmt.Println(runtime.NumGoroutine()) // 3

    time.Sleep(100 * time.Millisecond)

}

func init() {

    go main()

    go main()

}


这里当前的 goroutine运行新的 goroutine,所以这里我们有多个 goroutine,它再次执行main()。在线试用:


package main


import (

    "fmt"

    "runtime"

    "sync/atomic"

    "time"

)


func main() {

    fmt.Println(runtime.NumGoroutine()) // 1 2 3 4

    if atomic.LoadInt32(&i) <= 0 {

        return

    }

    atomic.AddInt32(&i, -1)

    go main()

    time.Sleep(100 * time.Millisecond)

}


var i int32 = 3

输出:


1

2

3

4

这里我们有一个maingoroutine 加上 3 个名为 goroutines 的用户main,所以这里的 goroutine 总数是 4。


让我们使用main()(一个 goroutine - 不需要同步)来计算阶乘。在线试用:


package main


import "fmt"


func main() {

    if f <= 0 {

        fmt.Println(acc)

        return

    }

    acc *= f

    f--

    main()

}


var f = 5

var acc = 1


输出:


120

注意:上面的代码只是为了清楚地表达我的观点,不利于生产使用(使用全局变量不应该是首选)。


查看完整回答
反对 回复 2023-05-08
?
暮色呼如

TA贡献1853条经验 获得超9个赞

是的。Main func 可以生成其他 goroutine,但“main”本身就是一个 goroutine。


package main


import (

        "fmt"

        "runtime"

)


func main() {

        // Goroutine num includes main processing

        fmt.Println(runtime.NumGoroutine()) // 1


        // Spawn two goroutines

        go func() {}()

        go func() {}()


        // Total three goroutines run

        fmt.Println(runtime.NumGoroutine()) // 3

}


查看完整回答
反对 回复 2023-05-08
  • 3 回答
  • 0 关注
  • 100 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信