为什么goroutines上没有`.join`操作?

时间:2016-12-02 15:53:55

标签: go goroutine

为什么goroutines上没有.join操作(即阻止完成)操作?而不是必须使用渠道来沟通什么时候在主要的goroutine进行?

感觉我错过了关于CSP理论的基本信息。

修改 我问" 为什么是这样的",而不是" 我是如何完成这个"。

2 个答案:

答案 0 :(得分:3)

这只是因为 goroutines不是线程。 Go运行时可以将给定的goroutine调度为与操作系统线程相关联,但是例如在阻塞I / O操作的情况下,所述线程可以与其他goroutine相关联,而另一个goroutine正在等待。

这是什么意思?

加入需要一个同步对象才能知道线程何时完成。由于Go的goroutine实际上只是非常轻量级的对象,只有堆栈,所以它们不直接提供这样的同步对象。

Go的CSP前提是,您可以非常便宜地实现数千个goroutine,并且只使用与物理CPU核心一样多的线程。 从操作系统的角度来看,同步对象很昂贵,因此每个goroutine都有这样的对象效率很低。

相反,通过使用同步包中的频道或WaitGroup来实现同步。

答案 1 :(得分:0)

紧跟@SirDius' detailed explanation

这是一个简单的示例,演示如何使用sync.Mutex执行此操作。我在这里选择了sync.Mutex而不是sync.WaitGroup,因为我只打算将每个Thread对象包装一个goroutine,并且WaitGroups打算与多个goroutine一起使用。

type Thread struct {
    body func()
    mux sync.Mutex
}

func NewThread(body func ()) *Thread {
    return &Thread{
        body: body,
    }
}

func (thread *Thread) Start() {
    thread.mux.Lock()
    go thread.run()
}

func (thread *Thread) Join() {
    thread.mux.Lock()
    thread.mux.Unlock()
}

func (thread *Thread) run() {
    thread.body()
    thread.mux.Unlock()
}

您可以按以下方式使用它

func main() {
    t := NewThread(t1)
    t.Start()
    t.Join()
    print("Thread 1: Joined\n")
}

func t1() {
    print("Thread 1: Started\n")
    time.Sleep(5 * time.Second)
    print("Thread 1: Completed\n")
}