Go 如何在戈兰脱颖而出
我在golang有一个程序,计算sha1并打印以两个零开始的sha1。我想使用goroutines和channels。我的问题是,如果我不知道select子句将产生多少结果,我不知道如何优雅地退出它 许多教程都知道这一点,并在计数器命中时退出。其他人建议使用WaitGroups,但我不想这样做:我想在主线程中打印结果,只要它出现在频道中。有些人建议在goroutines完成时关闭一个通道,但我想在异步完成后关闭它,所以我不知道如何关闭 请帮助我达到我的要求:Go 如何在戈兰脱颖而出,go,channels,Go,Channels,我在golang有一个程序,计算sha1并打印以两个零开始的sha1。我想使用goroutines和channels。我的问题是,如果我不知道select子句将产生多少结果,我不知道如何优雅地退出它 许多教程都知道这一点,并在计数器命中时退出。其他人建议使用WaitGroups,但我不想这样做:我想在主线程中打印结果,只要它出现在频道中。有些人建议在goroutines完成时关闭一个通道,但我想在异步完成后关闭它,所以我不知道如何关闭 请帮助我达到我的要求: package main impo
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}
}
}
主程序包
进口(
“加密/sha1”
“fmt”
“时间”
“运行时”
“数学/兰德”
)
类型哈希结构{
消息字符串
哈希[sha1.Size]字节
}
变量计数器int=0
var max int=100000
var channel=make(chan散列)
var source=rand.NewSource(time.Now().UnixNano())
var生成器=新随机数(源)
func main(){
nCPU:=runtime.numpu()
runtime.GOMAXPROCS(nCPU)
fmt.Println(“CPU数量:”,nCPU)
开始:=时间。现在()
对于i:=0;i case hash:=可能应该重新检查程序的结构。
这是一个工作的例子,我想你正在寻找什么。
它可以在计算机上运行
主程序包
进口(
“加密/sha1”
“fmt”
“数学/兰德”
“运行时”
“时间”
)
类型哈希结构{
消息字符串
哈希[sha1.Size]字节
}
常数Max int=100000
func main(){
nCPU:=runtime.numpu()
runtime.GOMAXPROCS(nCPU)
fmt.Println(“CPU数量:”,nCPU)
哈希:=生成()
开始:=时间。现在()
对于哈希:=范围哈希{
fmt.Printf(“哈希是%v\n”,哈希)
}
fmt.Printf(“自(开始)以来%v sha1的计数花费了%v\n”,最大值,时间)
}
func Generate()首先:如果你不知道你的计算何时结束,你怎么能对它建模呢?确保你确切知道你的程序何时和在什么情况下终止。如果你完成了,你知道如何用代码编写它
你基本上是在处理一个生产者-消费者问题。一个标准案例。我会建模
这样做():
制作人
WaitGroup
的目的是等待生成的goroutines完成,由
在goroutines中调用wg.Done
旁注
还要注意,您使用的Rand
对于并发访问是不安全的。请使用初始化的
在math/rand
中全局显示。示例:
rand.Seed(time.Now().UnixNano())
rand.Int()
func producer(max int, out chan<- Hash, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < max; i++ {
random := fmt.Sprintf("This is a test %v", rand.Int())
hash := sha1.Sum([]byte(random))
if hash[0] == 0 && hash[1] == 0 {
out <- Hash{random, hash}
}
}
close(out)
}
func consumer(max int, in <-chan Hash, wg *sync.WaitGroup) {
defer wg.Done()
for {
hash, ok := <-in
if !ok {
break
}
fmt.Printf("Hash is %v\n ", hash)
}
}
wg := &sync.WaitGroup{}
c := make(chan Hash)
wg.Add(1)
go producer(max, c, wg)
wg.Add(1)
go consumer(max, c, wg)
wg.Wait()
rand.Seed(time.Now().UnixNano())
rand.Int()