Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何在戈兰脱颖而出_Go_Channels - Fatal编程技术网

Go 如何在戈兰脱颖而出

Go 如何在戈兰脱颖而出,go,channels,Go,Channels,我在golang有一个程序,计算sha1并打印以两个零开始的sha1。我想使用goroutines和channels。我的问题是,如果我不知道select子句将产生多少结果,我不知道如何优雅地退出它 许多教程都知道这一点,并在计数器命中时退出。其他人建议使用WaitGroups,但我不想这样做:我想在主线程中打印结果,只要它出现在频道中。有些人建议在goroutines完成时关闭一个通道,但我想在异步完成后关闭它,所以我不知道如何关闭 请帮助我达到我的要求: package main impo

我在golang有一个程序,计算sha1并打印以两个零开始的sha1。我想使用goroutines和channels。我的问题是,如果我不知道select子句将产生多少结果,我不知道如何优雅地退出它

许多教程都知道这一点,并在计数器命中时退出。其他人建议使用WaitGroups,但我不想这样做:我想在主线程中打印结果,只要它出现在频道中。有些人建议在goroutines完成时关闭一个通道,但我想在异步完成后关闭它,所以我不知道如何关闭

请帮助我达到我的要求:

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;icase 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()