SHA1 をカウントし、2 つのゼロで始まるものを出力する golang のプログラムがあります。ゴルーチンとチャネルを使用したい。私の問題は、生成される結果の数がわからない場合、select 句を適切に終了する方法がわからないことです。
多くのチュートリアルはそれを事前に知っており、カウンターがヒットすると終了します。他の人は WaitGroups を使用することを提案していますが、私はそうしたくありません。結果がチャネルに表示されたらすぐにメイン スレッドに出力したいのです。ゴルーチンが終了したらチャネルを閉じることを提案する人もいますが、非同期の終了後にチャネルを閉じたいので、方法がわかりません。
私の要件を達成するのを手伝ってください:
package main
import (
"crypto/sha1"
"fmt"
"time"
"runtime"
"math/rand"
)
type Hash struct {
message string
hash [sha1.Size]byte
}
var counter int = 0
var max int = 100000
var channel = make(chan Hash)
var source = rand.NewSource(time.Now().UnixNano())
var generator = rand.New(source)
func main() {
nCPU := runtime.NumCPU()
runtime.GOMAXPROCS(nCPU)
fmt.Println("Number of CPUs: ", nCPU)
start := time.Now()
for i := 0 ; i < max ; i++ {
go func(j int) {
count(j)
}(i)
}
// close channel here? I can't because asynchronous producers work now
for {
select {
// how to stop receiving if there are no producers left?
case hash := <- channel:
fmt.Printf("Hash is %v\n ", hash)
}
}
fmt.Printf("Count of %v sha1 took %v\n", max, time.Since(start))
}
func count(i int) {
random := fmt.Sprintf("This is a test %v", generator.Int())
hash := sha1.Sum([]byte(random))
if (hash[0] == 0 && hash[1] == 0) {
channel <- Hash{random, hash}
}
}