为什么goroutines上没有.join
操作(即阻止完成)操作?而不是必须使用渠道来沟通什么时候在主要的goroutine进行?
感觉我错过了关于CSP理论的基本信息。
修改 我问" 为什么是这样的",而不是" 我是如何完成这个"。
答案 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")
}