3 回答
TA贡献1155条经验 获得超0个赞
当主goroutine退出时,程序终止,因此dispatcher()没有时间做任何事情。您需要封锁main()直到dispatcher()完成。通道可用于此目的:
package main
import (
"fmt"
"os"
"bufio"
)
var done = make(chan bool) // create channel
// Load files and send them into a channel for mappers reading.
func dispatcher(arr []string,channel chan string) {
for _,path := range arr {
file,err := os.Open(path)
fmt.Println("begin to dispatch ", path)
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
defer file.Close()
reader := bufio.NewReaderSize(file, 32*10*1024)
i := 0
for {
line,_ := reader.ReadString('\n')
channel <- line
i++
if i%200 == 0 {
fmt.Println(i," lines parsed")
}
}
fmt.Println("finish dispatch ", path)
}
done <- true // notify main() of completion
}
func main() {
path := os.Args
if len(path) < 2 {
fmt.Println("Need Input Files")
os.Exit(0)
}
channel := make(chan string)
fmt.Println("before dispatcher")
go dispatcher(path[1:],channel)
<-done // wait for dispatcher()
fmt.Println("after dispatcher")
}
TA贡献1810条经验 获得超4个赞
我修改了您的示例,使其在没有文件I / O的Go操场上运行;而是在频道上发送随机数。
@Victor Deryagin的解释和他使用“完成”频道的建议是正确的。出现死锁的原因是您的goroutine在通道上发送,但没有人从该通道中读取数据,因此该程序此时被卡住。在上面的链接中,我添加了一个消费者goroutine。然后,程序将按预期并发运行。
请注意,要等待几个goroutine,使用sync.WaitGroup会更清晰,更轻松。
TA贡献1815条经验 获得超13个赞
在原始问题中需要解决两个问题。
发送完所有数据后,您必须关闭通道。在func中
laodData
,请使用close(channel)发布所有数据。传递
sync.Waitgroup
作为参考。您将wg作为参数中的值发送给以下函数...laodData
和调度程序函数。
解决这两个问题将解决您的死锁问题。代码中出现死锁的原因如下:
不关闭发送通道将导致下游通道等待更长的时间。
发送参数
sync.Waitgroup
as作为值。应该将其作为参考发送,否则它将创建您要发送的对象的新副本。
- 3 回答
- 0 关注
- 225 浏览
添加回答
举报