我有一个主要运行一个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
}
}
}
}
“......这将使孩子处理僵尸”
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
你需要一个发送声明。例如。:
done <- true
the Go Tour和Effective Go提供了更多解释性文本和示例。
......还有第二个原因:
(2)因为,即使你将接收操作更改为发送语句,在它发送到通道并返回之间的作业goroutine中也没有任何关系,所以它不可能在任何时间从一个传递到下一个。如果您希望发生这种情况,请使用time
package在作业中添加睡眠:
done <- true
time.Sleep(time.Second * 30)
return
通过这些更改,您的主要将在完成通道后退出
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
}
}
}
}
你需要给你的完成频道添加一些bool消息,然后<-jobDone
}
可以得到一些消息来完成块