これで、golangを使用して、それが提供する並行性をより詳しく調べていきます。私はgoルーチンを使用して電話番号の文字列の順列を実装しようと決めました。WaitGroupは以前のWaitが返される前に再利用されます
私は、使用しているgoルーチンを調整するためにsync.WaitGroupを使用している問題に遭遇しています。特定のエラービーイング:
WaitGroup is reused before previous Wait has returned
コードビーイング:
main.go
package main
import (
"fmt"
"sync"
"github.com/sbiscigl/phonenumberperm/intstack"
"github.com/sbiscigl/phonenumberperm/permutations"
)
var wg sync.WaitGroup
func main() {
num := []int{2, 7, 1, 4, 5, 5, 2}
stack := intstack.New(num)
permutationChannel := make(chan string)
wg.Add(1)
go permutations.ThreadSafeCalcWords(stack, "", permutationChannel, &wg)
wg.Wait()
/*Then consume, but not implimented*/
}
順列/
package permutations
import (
"fmt"
"sync"
"github.com/sbiscigl/phonenumberperm/intstack"
)
var letterMap = map[int][]string{
2: []string{"a", "b", "c"},
3: []string{"d", "e", "f"},
4: []string{"g", "h", "i"},
5: []string{"j", "k", "l"},
6: []string{"m", "n", "o"},
7: []string{"p", "q", "r", "s"},
8: []string{"t", "u", "v"},
9: []string{"w", "x", "y", "z"},
}
func ThreadSafeCalcWords(s intstack.IntStack, word string, ch chan<- string,
wg *sync.WaitGroup) {
if s.IsEmpty() {
ch <- fmt.Sprint(word)
wg.Done()
} else {
/*Check to see if the values are 1 or zero as they*/
/*have no letters associated with them*/
if s.Peek() == 1 || s.Peek() == 0 {
wg.Done()
s.Pop()
wg.Add(1)
go ThreadSafeCalcWords(s, word, ch, wg)
} else {
wg.Done()
for _, letter := range letterMap[s.Pop()] {
wg.Add(1)
go ThreadSafeCalcWords(s, word+letter, ch, wg)
}
}
}
}
intstack/intstack.go
perm.goしたがって、調査の後、その行がwg.Wait()またはwaitheの待機中に呼び出されます。私は小さなプログラムで再現しようとしましたが、できませんでした。私の仮説は、goルーチンを呼び出した後にWait()に達すると、もはや待機グループを編集できなくなるが、それは間違っているということです。これが起こってしまう理由に任意の洞察力がrefrenceため
レポはで見つけることができ、参考になる:ThreadSafeCalcWords
であなたの再帰的な例ではhttps://github.com/sbiscigl/phonenumberperm