我有一个运行go例程的主程序的代码摘录。为什么这不会发生:主要退出收到完成后和作业返回之前,这将使孩子处理僵尸。任何对golang文档的引用都会有所帮助。
func main() {
var jobDone = make(chan bool)
go job(jobDone)
<-jobDone
}
func job(done chan bool) {
for {
select {
case <-someOtherGlobalChannel:
//Please ignore this case/channel
fmt.Println("SOmeOtherChannel received")
default:
if check_somthing_expression {
done <- true
return
}
}
}
}
答案 0 :(得分:2)
通过这些更改,您的主要将在完成频道后退出
package main
import (
"fmt"
)
func main() {
var jobDone = make(chan bool)
go job(jobDone)
<-jobDone
}
func job(done chan bool) {
for {
select {
case <-someOtherGlobalChannel:
//Please ignore this case/channel
fmt.Println("SOmeOtherChannel received")
default:
if check_somthing_expression {
done <- true
return
}
}
}
}
答案 1 :(得分:1)
“......这会让孩子处理僵尸”
go job()
没有开始一个单独的过程,它启动另一个goroutine。您在此计划中拥有main
goroutine和job
goroutine。 Language spec:
“go”语句在同一地址空间内作为独立的并发控制线程或goroutine开始执行函数调用。
因此,您不会创建Unix僵尸进程。
“为什么这不会发生:主要退出收到完成后和工作返回之前......?”
(1)因为done
中的频道job
没有发送声明。
<-done
是接收操作。见"Receive operator" in Go spec:
对于频道类型的操作数
ch
,接收操作<-ch
的值是从频道ch
收到的值。
另见"Send statements" in Go spec:
ch <- 3 // send value 3 to channel ch
您需要发送声明。 E.g:
done <- true
the Go Tour和Effective Go中提供了更多解释性文字和示例。
......还有第二个原因:
(2)因为,即使你将接收操作更改为发送语句,在它发送到通道并返回之间的作业goroutine中也没有任何关系,因此它不可能在任何时间从一个通过到下一个。如果您希望这样,请使用time
package:
done <- true
time.Sleep(time.Second * 30)
return
答案 2 :(得分:0)
你需要给你完成的频道添加一些bool消息,然后<-jobDone
}
可以得到一些消息来完成该块