我正在尝试在 Go 中编写一个函数来监视通道并记录通过它发送的内容。
func monitorChannel(inChannel, outChannel reflect.Value, fid int64, cond *sync.Cond) {
for {
cond.L.Lock()
var toLog reflect.Value
var ok bool
for toLog, ok = inChannel.TryRecv() ; !toLog.IsValid(); { // while no value received
if !ok {
cond.L.Unlock()
return
}
cond.Wait()
}
outChannel.Send(toLog)
logMessage("a", "b", inChannel.Interface(), toLog.Interface(), fid)
cond.L.Unlock()
}
}
这个函数应该从 inChannel 接收,记录发送的消息并通过 outChannel 发送它。由于我希望能够记录双向通道,因此我为每个要记录的通道调用此函数两次,交换 inChannel 和 outChannel。锁是为了防止两个 goroutine 在彼此之间传递消息。“fid”只是日志文件的ID。
但是当我运行以下测试代码时,我遇到了死锁:
errsIn := make(chan int64)
errsOut := make(chan int64)
cond := sync.NewCond(&sync.Mutex{})
go monitorChannel(reflect.ValueOf(errsIn), reflect.ValueOf(errsOut), fid, cond)
go monitorChannel(reflect.ValueOf(errsOut), reflect.ValueOf(errsIn), fid, cond)
errsIn <- 1
if <-errsOut != 1 {
t.Fatal("lost value through channel send")
}
errsOut <- 1
if <-errsIn != 1 {
t.Fatal("lost value through channel send")
}
即使我没有关闭通道,TryRecv 似乎在其第二个返回值上返回 false。为什么是这样?我该怎么办?
我在 Windows 8 64 位上运行 go 1.0.3。
手掌心
相关分类