【问题标题】:Printing Issue with Concurrent Routines in GoGo 中并发例程的打印问题
【发布时间】:2012-01-11 10:49:22
【问题描述】:

我有三个这样的并发例程,

func Routine1() {

Print (value a, value b, value c)
Print (value a, value b, value c)
Print (value a, value b, value c)

}

func Routine2() {
Print (value e, value f, value g)
Print (value e, value f, value g)
Print (value e, value f, value g)
}
func Routine3() {
Print (value x, value y, value z)
Print (value x, value y, value z)
Print (value x, value y, value z)
}

func main() {
go Routine1(command12, response12, command13, response13)
go Routine2(command12, response12, command23, response23)
Routine3(command13, response13, command23, response23)
}

现在我面临的问题是,有时会发生这样的情况,作为三个并发例程的结果,有时打印语句没有正确执行意味着没有打印完整,有一些东西被另一个打印插入。例如,例程 1 的 Print (value a, value b, value c) 给出的输出类似于值 a、值 b、值 g,其中值 g 是由例程 2 插入的。有人可以建议我,我该如何阻止它?我已经尝试过同步互斥程序。但是可能是因为我的代码太长并且可能我无法以正确的方式进行锁定解锁,所以它给出了死锁错误。谁能建议我如何以简单的方式或风险较小的同步互斥程序实现这些。

关于我的这个问题的更多信息可以找到here

【问题讨论】:

    标签: go concurrency goroutine


    【解决方案1】:

    您描述的打印不是原子操作。尝试使用 Go 方式,而不是使用互斥锁。将通道传递给每个接受字符串的 goroutine。每次你想打印一些东西时,只需将字符串发送到那个通道。

    一个单独的 goroutine 只是从该通道读取并打印出来的任何内容。这样就不需要锁了。

    package main
    
    import (
        "fmt"
        "sync"
    )
    
    func main() {
        var wg sync.WaitGroup
        wg.Add(2) // 2 routines we need to wait for.
    
        stdout := make(chan string)
    
        go routine1(&wg, stdout)
        go routine2(&wg, stdout)
        go printfunc(stdout)
    
        wg.Wait()
    
        close(stdout)
    }
    
    func routine1(wg *sync.WaitGroup, stdout chan<- string) {
        defer wg.Done()
    
        stdout <- "first print from 1"
        // do stuff
        stdout <- "second print from 1"
    }
    
    func routine2(wg *sync.WaitGroup, stdout chan<- string) {
        defer wg.Done()
    
        stdout <- "first print from 2"
        // do stuff
        stdout <- "second print from 2"
    }
    
    func printfunc(stdout <-chan string) {
        for {
            select {
            case str := <- stdout:
                fmt.Println(str)
            }
        }
    }
    

    【讨论】:

    • 谢谢。这是一个非常好的程序。让我试试。
    猜你喜欢
    • 2021-11-17
    • 2012-01-04
    • 1970-01-01
    • 2018-03-12
    • 2018-01-02
    • 2019-04-02
    • 1970-01-01
    • 2012-01-11
    • 1970-01-01
    相关资源
    最近更新 更多