4

私は外出先でデッドロックの問題に少し立ち往生しています。

このプログラムは、intの配列aを取り、それを2つに分割します。次に、これら2つの部分を2つの異なるルーチンに取り、すべての要素を合計します。この後、チャネルresで2つの結果を送信することになっています。次に、2つの解像度(現在はch)を足して、印刷する必要があります。

私の問題:クローズ関数を頻繁に移動することでデッドロックの問題に対処しようとしましたが、何も役に立たないようです。明らかに1つのルーチンAddを実行するだけでうまく機能します。

package main

import (
    "fmt"
)

// Add adds the numbers in a and sends the result on res.
func Add(a []int, res chan<- int) {
    sum := 0
    for i := range a {
        sum = sum + a[i]
    }
    res <- sum
}

func main() {
    a := []int{1, 2, 3, 4, 5, 6, 7}

    n := len(a)
    ch := make(chan int)
    go Add(a[:n/2], ch)
    go Add(a[n/2:], ch)


    sum := 0
    for s := range ch {
        sum = sum + s
    }
    //close(ch)

    fmt.Println(sum)
}
4

1 に答える 1

4

チャンネルを閉じることは決してないので、終了する合図はありませんrange。受信を試み続けるだけですが、送信するものは何も残っていません。

Add()関数が最後の関数であるかどうかを確認してチャネルを作成できるようにする方法が必要になるか、ループclose()で使用する代わりにカウンターをデクリメントして、range必要がないようにすることができます。を使用しますclose()

func main() {
    a := []int{1, 2, 3, 4, 5, 6, 7}

    n := len(a)
    ch := make(chan int)
    go Add(a[:n/2], ch)
    go Add(a[n/2:], ch)

    sum := 0

    // counts the number of messages sent on the channel
    count := 0

    // run the loop while the count is less than the total number of routines
    for count < 2 {
        s := <-ch
        sum = sum + s
        count++  // Increment the count after a routine sends its value
    }
    fmt.Println(sum)
}

デモ: http: //play.golang.org/p/oHcrUStjmm

于 2013-03-19T23:51:02.610 に答える