2013-05-16 65 views
0

爲什麼即使我只通過一個通道並從通道獲取一個輸出,也會出現死鎖?go功能通道中的死鎖

package main 

import "fmt" 
import "math/cmplx" 

func max(a []complex128, base int, ans chan float64, index chan int) { 

    fmt.Printf("called for %d,%d\n",len(a),base) 

    maxi_i := 0 
    maxi := cmplx.Abs(a[maxi_i]); 

    for i:=1 ; i< len(a) ; i++ { 
     if cmplx.Abs(a[i]) > maxi { 
      maxi_i = i 
      maxi = cmplx.Abs(a[i]) 
     } 
    } 

    fmt.Printf("called for %d,%d and found %f %d\n",len(a),base,maxi,base+maxi_i) 

    ans <- maxi 
    index <- base+maxi_i 
} 

func main() { 
    ans := make([]complex128,128) 

    numberOfSlices := 4 
    incr := len(ans)/numberOfSlices 
    tmp_val := make([]chan float64,numberOfSlices) 
    tmp_index := make([]chan int,numberOfSlices) 
    for i,j := 0 , 0; i < len(ans); j++{ 
     fmt.Printf("From %d to %d - %d\n",i,i+incr,len(ans)) 
     go max(ans[i:i+incr],i,tmp_val[j],tmp_index[j]) 

     i = i+ incr 
    } 
//After Here is it stops deadlock 
    maximumFreq := <- tmp_index[0] 
    maximumMax := <- tmp_val[0] 
    for i := 1; i < numberOfSlices; i++ { 

     tmpI := <- tmp_index[i] 
     tmpV := <- tmp_val[i] 

     if(tmpV > maximumMax) { 
      maximumMax = tmpV 
      maximumFreq = tmpI 
     } 
    } 

    fmt.Printf("Max freq = %d",maximumFreq) 

} 

回答

2

對於那些閱讀這個問題,也許想知道爲什麼他的代碼失敗這裏的解釋。

當他構建自己的渠道片,像這樣:

tmp_val := make([]chan float64,numberOfSlices) 

他讓道,每一個指數的通道零值的切片。一個頻道零值是零,因爲頻道是參考類型,一個零頻道塊永遠發送,並且由於在零頻道中沒有任何東西,它也將永遠阻止接收。因此你會陷入僵局。

當無足輕重的循環會改變他的代碼來構建每個通道單獨使用

tmp_val[i] = make(chan float64) 

他構建了非空的通道,一切都很好。

1

我做錯了陳的陳。應該已經做

numberOfSlices := 4 
incr := len(ans)/numberOfSlices 
var tmp_val [4]chan float64 
var tmp_index [4]chan int 

for i := range tmp_val { 
    tmp_val[i] = make(chan float64) 
    tmp_index[i] = make(chan int) 
} 

for i,j := 0 , 0; i < len(ans); j++{ 
    fmt.Printf("From %d to %d [j:%d] - %d\n",i,i+incr,j,len(ans)) 
    go maximumFunc(ans[i:i+incr],i,tmp_val[j],tmp_index[j]) 

    i = i+ incr 
}