通道结束父例程后返回

问题描述 投票:0回答:3

我有一个主要运行一个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 concurrency
3个回答
1
投票

Zombie Process

“......这将使孩子处理僵尸”

go job()没有开始一个单独的过程,它开始另一个goroutine。你有一个main goroutine和一个job goroutine在这个节目中。 Language spec

“go”语句在同一地址空间内作为独立的并发控制线程或goroutine开始执行函数调用。

因此,您将不会创建Unix僵尸进程。

Main Not Exiting Before Job

“为什么这不会发生:主要退出收到完成后和工作返回之前......?”

原因#1:接收操作阻止两个Goroutines

(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 TourEffective Go提供了更多解释性文本和示例。

......还有第二个原因:

理由2:发送和返回之间没有任何关系

(2)因为,即使你将接收操作更改为发送语句,在它发送到通道并返回之间的作业goroutine中也没有任何关系,所以它不可能在任何时间从一个传递到下一个。如果您希望发生这种情况,请使用time package在作业中添加睡眠:

done <- true
time.Sleep(time.Second * 30)
return

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
            }
        }
    }
}

0
投票

你需要给你的完成频道添加一些bool消息,然后<-jobDone }可以得到一些消息来完成块

© www.soinside.com 2019 - 2024. All rights reserved.