2

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

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 插入的。有人可以建议我,我该如何阻止它?我已经尝试过同步互斥程序。但是可能是因为我的代码太长并且可能我无法以正确的方式进行锁定解锁,所以它给出了死锁错误。任何人都可以建议我如何以简单的方式或风险较小的同步互斥程序实现这些。

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

4

1 回答 1

6

Printing as you describe it is not an atomic operation. Instead of using mutexes, try the Go way. Pass a channel into each goroutine which accepts a string. Every time you want to print something, just send the string into that channel.

A separate goroutine does nothing more than read from that channel and prints whatever comes out. This way there is no need for locks.

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)
        }
    }
}
于 2011-12-02T14:34:21.553 回答