GOLANG: fatal error: all goroutines are asleep - deadlock
GOLANG: fatal error: all goroutines are asleep - deadlock
package main
import (
"fmt"
"os"
"os/exec"
"bufio"
"reflect"
)
func runTheCommand(ch chan<- string, cmD string) {
ouT,_ := exec.Command("sh","-c",cmD).Output()
ch <- string(ouT)
}
// Readln returns a single line (without the ending \n) from the input buffered reader. An error is returned iff there is an error with the buffered reader.
func Readln(r *bufio.Reader) (string, error) {
var (isPrefix bool = true
err error = nil
line, ln []byte
)
for isPrefix && err == nil {
line, isPrefix, err = r.ReadLine()
ln = append(ln, line...)
}
return string(ln),err
}
func main() {
var chans = []chan string{}
f, _ := os.Open("../tmpStatus.config")
r := bufio.NewReader(f)
cmD, e := Readln(r)
for e == nil {
ch := make(chan string)
chans = append(chans, ch)
go runTheCommand(ch,cmD)
cmD,e = Readln(r)
}
cases := make([]reflect.SelectCase, len(chans))
for i, ch := range chans {
cases[i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch)}
}
remaining := len(cases)
for remaining > 0 {
chosen, value, ok := reflect.Select(cases)
if !ok {
cases[chosen].Chan = reflect.ValueOf(nil)
remaining -= 1
continue
}
fmt.Printf("%s", value.String())
}
}
此代码正确打印出所有从通道接收到的值。
但最后它退出并出现以下错误:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [select]: reflect.rselect(0xc200283480, 0x22, 0x22,
0xffffffffffffffff, 0x0, ...)
/usr/local/go/src/pkg/runtime/chan.c:1212 +0x10d
reflect.Select(0xc200066800, 0x22, 0x22, 0x1, 0x0, ...)
/usr/local/go/src/pkg/reflect/value.go:1957 +0x1fb
我是GO的新人。我参考了 google 并以某种方式设法编写了一个工作代码。我不完全理解这个脚本是如何工作的,尤其是 reflect package 命令。我的目的是并行执行 ../tmpStatus.config 文件中列出的 unix 命令并打印出结果。我对 GO 提供的并发特性感到兴奋,因此决定尝试一下。现在它打印结果的速度如此之快。到现在为止,我都是在 python 中一个接一个地做这件事。
我 运行 这个脚本在 go 版本 go1.1.2 linux/amd64 安装到自定义位置。
知道为什么会发生死锁吗?
您似乎正在尝试从文件中读取数据,然后将工作分配给多个工作人员(扇出)。我没有看到您的代码中有任何通道关闭。有关我所指模式的示例,请参阅 https://gist.github.com/kylewolfe/7c54018a9ed16517c0dd。对于文件的每一行,您将读入一个通道,x 名工作人员将从中读取(并反映/做工作)。
package main
import (
"fmt"
"os"
"os/exec"
"bufio"
"reflect"
)
func runTheCommand(ch chan<- string, cmD string) {
ouT,_ := exec.Command("sh","-c",cmD).Output()
ch <- string(ouT)
}
// Readln returns a single line (without the ending \n) from the input buffered reader. An error is returned iff there is an error with the buffered reader.
func Readln(r *bufio.Reader) (string, error) {
var (isPrefix bool = true
err error = nil
line, ln []byte
)
for isPrefix && err == nil {
line, isPrefix, err = r.ReadLine()
ln = append(ln, line...)
}
return string(ln),err
}
func main() {
var chans = []chan string{}
f, _ := os.Open("../tmpStatus.config")
r := bufio.NewReader(f)
cmD, e := Readln(r)
for e == nil {
ch := make(chan string)
chans = append(chans, ch)
go runTheCommand(ch,cmD)
cmD,e = Readln(r)
}
cases := make([]reflect.SelectCase, len(chans))
for i, ch := range chans {
cases[i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch)}
}
remaining := len(cases)
for remaining > 0 {
chosen, value, ok := reflect.Select(cases)
if !ok {
cases[chosen].Chan = reflect.ValueOf(nil)
remaining -= 1
continue
}
fmt.Printf("%s", value.String())
}
}
此代码正确打印出所有从通道接收到的值。 但最后它退出并出现以下错误:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [select]: reflect.rselect(0xc200283480, 0x22, 0x22, 0xffffffffffffffff, 0x0, ...) /usr/local/go/src/pkg/runtime/chan.c:1212 +0x10d reflect.Select(0xc200066800, 0x22, 0x22, 0x1, 0x0, ...) /usr/local/go/src/pkg/reflect/value.go:1957 +0x1fb
我是GO的新人。我参考了 google 并以某种方式设法编写了一个工作代码。我不完全理解这个脚本是如何工作的,尤其是 reflect package 命令。我的目的是并行执行 ../tmpStatus.config 文件中列出的 unix 命令并打印出结果。我对 GO 提供的并发特性感到兴奋,因此决定尝试一下。现在它打印结果的速度如此之快。到现在为止,我都是在 python 中一个接一个地做这件事。 我 运行 这个脚本在 go 版本 go1.1.2 linux/amd64 安装到自定义位置。 知道为什么会发生死锁吗?
您似乎正在尝试从文件中读取数据,然后将工作分配给多个工作人员(扇出)。我没有看到您的代码中有任何通道关闭。有关我所指模式的示例,请参阅 https://gist.github.com/kylewolfe/7c54018a9ed16517c0dd。对于文件的每一行,您将读入一个通道,x 名工作人员将从中读取(并反映/做工作)。