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.")
}
顺便说一句,mr 是这个的实例:
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我想把这个资源放回去。将其放回 channel ,让下一个工作使用可用的工作人员。
为什么挂了? 谢谢
最佳答案
在 go 中,如果没有缓冲, channel 可以用于同步。在这里,负责消费 mr.registerChannel
的进程正在尝试写入它。当您从无缓冲 channel 读取或写入时,您将等到另一端有另一个进程分别写入或从 channel 读取。
因此,当此 block 尝试写入 channel 时,它会阻塞等待有人读取它所写的内容。由于此 block 也负责读取,因此它将在死锁中永远等待自己。您需要重新设计它,以便将字符串交还给其他东西来读取,或者您需要使用缓冲 channel 并且不要期望在读取行 worker_str = <- mr.registerChannel
上陷入困境.那将不得不重写为 for/select 或其他东西。
关于GoLang,把资源放回 channel 挂我的程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23796961/