blz*_*blz 1 concurrency channel go goroutine
下面是一个启动外部进程的函数,将正则表达式与进程的标准输出进行匹配,并返回匹配的内容.
func (c *Colony) startCircuit(peer *string) (string, error) {
var (
err error
cmd *exec.Cmd
anchorChan chan string
)
// ... (omitted for readability)
// get the anchor from standard output
go func() {
defer out.Close()
anchorChan = make(chan string)
for scanner := bufio.NewScanner(out); scanner.Scan(); {
line := scanner.Text()
if anchor := reRootAnchor.FindString(line); anchor != "" {
log.Println("Started circuit server with anchor:", anchor)
anchorChan <- anchor
break
}
}
}()
anchor := <-anchorChan
return anchor, err
}
Run Code Online (Sandbox Code Playgroud)
运行该函数时,我获得以下输出,表明确实找到了匹配并且(可能)被推入anchorChan:
2016/05/22 14:04:36 Started circuit server with anchor: circuit://[::]:36195/20666/Q431cc5fe613aa04b
Run Code Online (Sandbox Code Playgroud)
然而,startCircuit打电话似乎挂了.以下是相关的代码:
rootAnchor, err := c.startCircuit(peer)
if err != nil {
return "", err
}
log.Fatal(rootAnchor) // DEBUG
Run Code Online (Sandbox Code Playgroud)
为什么startCircuit无限期地悬挂而不是返回?
问题其实很简单.提示:以下代码以死锁结束.
package main
import "fmt"
func main() {
var c chan string
go func() {
c = make(chan string)
c <- "42"
}()
str := <-c
fmt.Println(str)
}
Run Code Online (Sandbox Code Playgroud)
从那里,问题是微不足道的.启动goroutine时,您的频道未初始化.有两个goroutines的比赛,显然去不能决定哪个应该优先考虑.
所以,你的答案是:make(chan ...)在goroutine开始之前调用,它应该解决你的问题.在有效的过程中有一个完美的例子.