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

时间:2009-11-16 01:33:40

标签: java c++ multithreading pthreads go

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

4 个答案:

答案 0 :(得分:23)

引自Day 3 Tutorial< - 请阅读此内容以获取更多信息。

  

Goroutines根据需要进行多路复用   到系统线程。当一个goroutine   执行阻塞系统调用,没有   其他goroutine被阻止了。

     

我们将对CPU绑定做同样的事情   goroutines在某些时候,但现在,   如果你想要用户级并行性   必须设置$ GOMAXPROCS。或者打电话   runtime.GOMAXPROCS(n)的

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

多个gououitine可在需要时多路复用到单个线程中。

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

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

答案 1 :(得分:14)

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

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

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

答案 2 :(得分:13)

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

简而言之,由于良好的沟通设施,使用线程存在“低摩擦”(如果可以的话,就像Erlang一样)。

答案 3 :(得分:5)

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

  

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

quote source

最大化我的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++ {

    }
}

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