为什么在 goroutines 上没有 `.join` 操作?
Why is there no `.join` operation on goroutines?
为什么goroutines没有.join
操作(即block until finished)操作?何时在主 goroutine 中进行而不是必须使用通道进行通信?
感觉好像我缺少有关 CSP 理论的一些基本知识。
编辑:
我问的是“为什么是这样”,而不是“我如何做到这一点”。
这仅仅是因为goroutines 不是线程。给定的 goroutine 可以由 Go 运行时调度以关联到操作系统线程,但是例如在阻塞 I/O 操作的情况下,所述线程可以关联到其他 goroutines 而另一个正在等待。
这是什么意思?
加入需要同步对象才能知道线程何时结束。由于 Go 的 goroutines 实际上只是一个非常轻量级的对象,只有一个栈,所以它们并没有直接提供这样的同步对象。
Go 的 CSP 前提是您可以非常便宜地实例化数千个 goroutine,并且只使用与物理 CPU 内核一样多的线程。
在 OS 的角度来看,同步对象是昂贵的,因此每个 goroutine 都有这样的对象是非常低效的。
相反,同步是通过使用同步包中的通道或 WaitGroup 实现的。
跟进
这是一个简单的示例,演示如何使用 sync.Mutex
执行此操作。我在这里选择 sync.Mutex
而不是 sync.WaitGroup
因为我只打算让每个 Thread
对象包装一个 goroutine,而 WaitGroups 旨在与多个 goroutines 一起使用。
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")
}
为什么goroutines没有.join
操作(即block until finished)操作?何时在主 goroutine 中进行而不是必须使用通道进行通信?
感觉好像我缺少有关 CSP 理论的一些基本知识。
编辑: 我问的是“为什么是这样”,而不是“我如何做到这一点”。
这仅仅是因为goroutines 不是线程。给定的 goroutine 可以由 Go 运行时调度以关联到操作系统线程,但是例如在阻塞 I/O 操作的情况下,所述线程可以关联到其他 goroutines 而另一个正在等待。
这是什么意思?
加入需要同步对象才能知道线程何时结束。由于 Go 的 goroutines 实际上只是一个非常轻量级的对象,只有一个栈,所以它们并没有直接提供这样的同步对象。
Go 的 CSP 前提是您可以非常便宜地实例化数千个 goroutine,并且只使用与物理 CPU 内核一样多的线程。 在 OS 的角度来看,同步对象是昂贵的,因此每个 goroutine 都有这样的对象是非常低效的。
相反,同步是通过使用同步包中的通道或 WaitGroup 实现的。
跟进
这是一个简单的示例,演示如何使用 sync.Mutex
执行此操作。我在这里选择 sync.Mutex
而不是 sync.WaitGroup
因为我只打算让每个 Thread
对象包装一个 goroutine,而 WaitGroups 旨在与多个 goroutines 一起使用。
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")
}