在Go中关闭自动进纸通道

我正在尝试使用Go中的并发性和渠道。我面临的问题主要是并发性,因此,我并没有放弃以下逻辑错误或应更改的逻辑。


我有一个缓冲通道,其缓冲大小为“ N”,它还表示将要创建的goroutine的数量。所有例程都从一个通道读取并在另一个通道中写入,而主要的goroutine将从最后一个通道中打印值。


1个输入通道--- N个goroutines查找并添加到输入和输出--- 1个输出通道


问题是我总是陷入僵局,因为我不知道如何关闭正在馈送自身的通道,也不知道何时停止,因此我也无法关闭输出通道。


该代码是以下示例:


package main


const count = 3

const finalNumber = 100


// There will be N routines running and reading from the one read channel

// The finalNumber is not known, in this examples is 100, but in the main problem will keep self feeding until the operation gives a wrong output

// readingRoutine will feed read channel and the print channel

func readingRoutine(read, print chan int) {

    for i := range read {

        print <- i

        if i < finalNumber && i+count < finalNumber {

            read <- i + count

        }

    }

}


// This is the main routine that will be printing the values from the print channel

func printingRoutine(print chan int) {

    for i := range print {

        println(i)

    }

}


func main() {

    read := make(chan int, count)

    print := make(chan int, count)


    // Feed count numbers into the buffered channel

    for i := 0; i < count; i++ {

        read <- i

    }


    // count go routines will be processing the read channel

    for i := 0; i < count; i++ {

        go readingRoutine(read, print)

    }

    printingRoutine(print)

}

在此示例中,它应打印从0到100的所有数字并完成。谢谢


慕森卡
浏览 208回答 2
2回答

牧羊人nacy

我通常会发现,如果您在使设计模式或想法可行时遇到真正的问题,那说明您做错了。在这种情况下,自给式例行程序的想法知道何时应关闭自身。我认为您正在寻找的是的想法worker pool。本质上,您有一个包含的集合的通道,work然后是workersgo例程形式的多个例程,它们从该通道读取作业并对其进行处理,直到完成所有工作为止。在以下示例中,我使用包gopool运行3个并发工作程序,这些工作程序由第4个go例程提供。我等待所有工人关闭自己,这是由于输入工作通道被关闭而造成的。// create the channel to store the jobs// notice that we can only have 5 jobs in the channel at one timeworkChan := make(chan int, 5)// here we define what should be happening in each of our workers.// each worker will be running concurrentlyvar work gopool.WorkFunc = func(ctx context.Context) error {&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-ctx.Done():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // this is just a get out clause in case we want to prematurely stop the workers while there is still work to do&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ctx.Err()&nbsp; &nbsp; &nbsp; &nbsp; case work, ok := <-workChan:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if !ok {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // we get here if the work channel has been closed&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return nil&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // do something with work here&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(work)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}// this func defines how many workers we want to be running concurrentlyvar workerCount gopool.WorkerCountFunc = func() uint64 {&nbsp; &nbsp; return 3}// here we define a new worker poolp := gopool.NewPool("test", work, workerCount, nil, context.TODO())// here we start the worker poolcancel, err := p.StartOnce()if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; panic(err)}// the workers are now running and waiting for jobs// we'll defer the cancel to make sure that the pool will be closed eventuallydefer cancel()// now we'll start a go routine to feed the workers// it does this by adding to the workChan, and closes workChan when there is no more work to do// when the workChan is closed the workers know that they should quitgo func(workChan chan<- int, min int, max int) {&nbsp; &nbsp; for i := min; i <= max; i++ {&nbsp; &nbsp; &nbsp; &nbsp; workChan <- i&nbsp; &nbsp; }&nbsp; &nbsp; close(workChan)}(workChan, 3, 200)// now we wait for the pool to be finished with it's work<-p.Done()fmt.Println("all work has been done")输出示例:$ go run main.go&nbsp;4678910351314151617181220211923242522272811303126332935363438393241423744434647404950515248545356575845606162636465555968696671727370757677677980748283818584878889789190939492969795999810110210310410010610710810910511111211011411511611711811912086122123124125126127121129113131128133134130136137132139138141140143144145146147148149150135151153142155156157158159160161162163164152154167165166170171172173174169176177178179180168182183184181185187188189190175186193191195194197196199198200192all work has been done
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go