for i := 0; i < mr.nMap; i++ {
DPrintf("worker number is %d\n", mr.workerNumber)
worker_str = <- mr.registerChannel
DPrintf("Worker_str is %s \n",worker_str)
args := &DoJobArgs{mr.file,"Map",i,mr.nReduce}
var reply DoJobReply
var ret bool
ret = call(worker_str, "Worker.DoJob", args, &reply)
if ret {
fmt.Println("wk worker done.\n")
fmt.Println(worker_str)
mr.registerChannel <- worker_str // <=======stuck here
} else
{
fmt.Println("wk worker fail.\n")
}
DPrintf("map finished.")
}
顺便说一句,先生就是这样的例子:
type MapReduce struct {
nMap int // Number of Map jobs
nReduce int // Number of Reduce jobs
file string // Name of input file
MasterAddress string
registerChannel chan string
DoneChannel chan bool
alive bool
l net.Listener
stats *list.List
// Map of registered workers that you need to keep up to date
Workers map[string]*WorkerInfo
// add any additional state here
workerNumber int
}
执行此操作时,我的代码会挂起"mr.registerChannel <- worker_str "
我真的不明白为什么。 worker_str可用,我想在使用此worker之后重新放入此资源。把它放回渠道,让下一份工作使用可用的工人。
为何挂起? 感谢
答案 0 :(得分:5)
在go中,如果没有缓冲,则可以使用通道进行同步。在这里,负责使用mr.registerChannel
的进程正在尝试写入它。当您读取或写入和未缓冲的通道时,您将等到另一端的另一个进程分别写入或从通道读取。
因此,当此块尝试写入通道时,它会阻止等待某人读取它所写的内容。由于这个块也负责读取,它将在死锁中永远等待自己。你需要重新设计这个,这样你就可以将字符串移回其他东西来阅读,或者你需要使用一个缓冲的通道,而不要指望在读取线worker_str = <- mr.registerChannel
上陷阱。那必须重写为for / select或者其他东西。