Go的多线程和pthread或Java线程有什么区别?

Fra*_*ank 32 c++ java multithreading pthreads go

Go的多线程方法和其他方法有什么区别,比如pthread,boost :: thread或Java Threads?

Ran*_*ku' 24

引自第3天教程 < - 阅读本文以获取更多信息.

Goroutines根据需要多路复用到系统线程上.当goroutine执行阻塞系统调用时,不会阻止其他goroutine.

我们将在某些时候为CPU绑定的goroutine做同样的事情,但是现在,如果你想要用户级并行,你必须设置$ GOMAXPROCS.或者调用runtime.GOMAXPROCS(n).

goroutine不一定对应于OS线程.它可以具有较小的初始堆栈大小,并且堆栈将根据需要增长.

当需要时,可以将多个gououitine多路复用到单个线程中.

更重要的是,这个概念如上所述,goroutine是一个顺序程序,可以阻止自己,但不会阻止其他goroutine.

Goroutines在gccgo中实现为pthread,因此它也可以与OS线程相同.它将OS线程的概念与编程时的多线程思想分开.


小智 14

在参考编译器(5g/6g/8g)中,主调度程序(src/pkg/runtime/proc.c)创建N OS线程,其中N由runtime.GOMAXPROCS(n)(默认值1)控制.每个调度程序线程从主列表中提取一个新的goroutine并开始运行它.goroutine将继续运行,直到进行系统调用(例如printf)或对通道进行操作,此时调度程序将抓取下一个goroutine并从它停止的位置运行它(参见在src/pkg/runtime/chan.c中调用gosched().

所有意图和目的的调度都是用协同程序实现的.可以使用setjmp()和longjmp()直接用C编写相同的功能,Go(以及实现轻量级/绿色线程的其他语言)只是为您自动化过程.

轻量级线程的好处是,因为它是所有用户空间,创建"线程"非常便宜(分配一个小的默认堆栈)并且由于线程如何相互通信的固有结构而非常有效.缺点是它们不是真正的线程,这意味着单个轻量级线程可以阻止整个程序,即使它看起来所有线程应该同时运行.


jld*_*ont 13

IMO,使Go中的多线程吸引人的是通信设施:与pthread不同,其中必须构建通信基础设施(互斥,队列等),在Go中它默认以方便的形式提供.

简而言之,由于良好的通信设施,使用线程存在"低摩擦"(如果我可以这么说,就像Erlang一样).


Pro*_*ter 5

正如之前的答案所述,go例程并不一定与系统线程相对应,但是如果你现在必须提高多线程的性能,我发现以下内容很有用:

默认情况下,Go运行时的当前实现不会并行化此代码.它仅将单个核心专用于用户级处理.系统调用中可以阻止任意数量的goroutine,但默认情况下,只有一个可以随时执行用户级代码.它应该更智能,有一天它会变得更聪明,但是如果你想要CPU并行性,你必须告诉运行时你想要同时执行代码的goroutine有多少.有两种相关的方法可以做到这一点.使用设置为要使用的核心数的环境变量GOMAXPROCS运行您的作业,或者导入运行时包并调用runtime.GOMAXPROCS(NCPU).一个有用的值可能是runtime.NumCPU(),它报告本地计算机上的逻辑CPU数.同样,随着调度和运行时间的改进,预计此要求将被淘汰.

引用来源

最大化我的i5处理器的示例程序是这样的(在htop中使用100%的所有4个核心):

package main


import (
    "fmt"
    "time"
    "runtime"
)


func main() {
    runtime.GOMAXPROCS(4) // Set the maximum number of threads/processes

    d := make(chan string)
    go boring("boring!", d, 1)
    go boring("boring!", d, 2)
    go boring("boring!", d, 3)
    go boring("boring!", d, 4)

    for i := 0; i < 10; i++ {
        time.Sleep(time.Second);
    }

    fmt.Println("You're boring; I'm leaving.")
}

func boring(msg string, c chan string, id int) {
    for i := 0; ; i++ {

    }
}
Run Code Online (Sandbox Code Playgroud)

现在它实际上并没有"做"任何事情,但是看看与其他语言(如Java)编写多线程应用程序相比有多简短/简单/简单.