2017-02-07 8 views
-2

なぜこれがデッドロックであるのかわからないのは初めてですか?私はメインgoroutingがdoSomething関数内のチャネルに複数回の書き込みしようとしているこれがゴランのデッドロックなのはなぜか分かりませんか?

func doSomething(c chan<- string){ // recursive function does something 
    c <- result 
    return dosomething(c) } 

func reads(c <-chan string){ 
    results := "" 
    temp := <-c   
    results = results + "\n" + temp  
    return results 
} 

func main(){  
    go reads(c) 
    doSomething(c) 
} 
+0

ことだろう偉大なそうでなければなりhttps://play.golang.org/使用して再現するような例を持っていますプロセスを理解するのが難しいでしょう。 – oivoodoo

+0

あなたの再帰が基本ケースを持っていることを確認し、すべての再帰呼び出しがあなたを基底ケースに近づけるようにします。 –

+0

遊び場が必要です。 – I159

答えて

1

forループを使用せずに読んで絶えずdoSomethingの結果を読み、機能に格納することにしたいです。 read機能はチャネルを1度だけ読み取っています。したがって、書き込み操作は、他のパーティがチャネルから読み取るまで待機します。メインのゴルーチンがブロックされると、デッドロックになります。

ブロッキング操作がメインゴルーチンにない場合、メインゴルーチンが終了するたびにGoプログラムが終了するので、プログラムは終了します。主な機能が終了する可能性がある場合、デッドロックは発生しません。

0

readsが同時に実行され、doSomethingが実行されていないため、空のチャネルから読み取ろうとしています。いくつかの方法で問題を解決することは可能です。正確なアーキテクチャや効率的なアプローチではないことに注意してください。以下の例は、元のスニペットの「デッドロック」問題を解決します。

読むと同時に書き込み:

package main 

func doSomething(c chan<- string) { // recursive function does something 
    c <- "result" 
    doSomething(c) 
} 

func reads(c <-chan string) { 
    results := <-c 
    fmt.Println("Boo", results) 
} 

func main() { 
    c := make(chan string) 
    go reads(c) 
    go doSomething(c) // Write concurrentely 
} 

使用selectはチャンネル読み出し動作を処理するために:私はむしろ、第一及び第二のアプローチの組み合わせを好む

func reads(c <-chan string) { 
    // Use select 
    select { 
    case res := <-c: 
     fmt.Println("received message", res) 
    default: 
     fmt.Println("no results received") 
    } 
} 

。書き込み後に読む

は(それは地獄のように正しい設計はほど遠い):

func main() { 
    c := make(chan string) 

    go doSomething(c) 
    reads(c) // Read after write 
} 
関連する問題