2014-05-22 3 views
1
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.") 

    } 

을 걸 채널로 다시 자원을 넣어 씨는이 인스턴스이다 . worker_str을 사용할 수 있으며이 작업자를 사용한 후에이 리소스를 다시 넣으려고합니다. 그것을 다시 채널에 놓고, 다음 일자리가 가능한 근로자를 이용하게하십시오.GoLang, 내 프로그램 BTW

왜 멈 춥니 까? 감사합니다.

답변

5

이동 중에 채널을 버퍼링하지 않으면 동기화 할 수 있습니다. 여기에서 mr.registerChannel을 소비하는 프로세스가이 프로세스에 쓰기를 시도하고 있습니다. 채널을 읽고 쓰거나 버퍼링하지 않은 채로 채널을 쓰거나 쓸 때까지 다른 프로세스가있을 때까지 기다릴 것입니다.

따라서이 블록이 채널에 쓰기를 시도하면 누군가가 작성한 것을 읽기 위해 기다리는 것을 차단합니다. 이 블록은 이기도하고 읽기를 담당하는이기 때문에 교착 상태가되어 영원히 기다립니다. 문자열을 다시 다른 것으로 넘겨 주거나 버퍼링 된 채널을 사용해야하고 읽기 라인 worker_str = <- mr.registerChannel에 트랩 할 필요가없는 경우 다시 설계해야합니다. 그것은 for/select 또는 something으로 다시 써야합니다.

+0

예, 도움이됩니다. 이제 버퍼링 된 채널을 사용하여 문제가 해결되었습니다. 코코를 감상하십시오. – BufBills

+3

요약하자면 ** 버퍼링을 추가하기 전에 교착 상태 문제를 해결하는 것이 좋습니다 **. 종종 버퍼링을 추가하는 것이 교착 상태 문제를 연기하기 만합니다. 무슨 일이 일어 났는지 이해하고 버퍼링 대신에 원인을 수정하는 것이 좋습니다. 그러나 버퍼링을 사용하면 성능이 크게 향상 될 수 있습니다. 따라서 오류 동작을 수정하는 대신 성능 튜닝 측면에서 버퍼링을 생각하는 것이 좋습니다. –