Go语言中临界区的交替执行

huangapple go评论86阅读模式
英文:

Alternate execution of critical sections in Go language

问题

我有两个Go协程:

func f1() {
    ... 一些代码

    // 临界区1(CS1)
    ... 临界区代码
    // 结束临界区1

    ... 更多代码
}

func f2() {
    ... 一些代码

    // 临界区2(CS2)
    ... 临界区代码
    // 结束临界区2

    ... 更多代码
}

func main() {
    go f1()
    go f2()
}

如何确保这些协程中的临界区始终交替执行呢?
换句话说,只有在CS2之后才执行CS1,反之亦然:CS1,CS2,CS1,CS2,CS1,等等。

英文:

I have two go routines:

func f1 { 
    ... some code 
       
    // critical section 1 (CS1)     
        ... critical section code                                   
    // end criticla section 1
    
    ... more code
}

func f2 { 
    ... some code 
       
    // critical section 2 (CS2)    
        ... critical section code                                
    // end criticla section 2
    
    ... more code
}

func main() {
   go f1()
   go f2()
}

What is proper way to ensure that the critical sections in these routines always execute alternately?
In other words, CS1 should be executed only after CS2 and vice versa: CS1, CS2, CS1, CS2, CS1, etc.

答案1

得分: 5

如果您在不同的goroutine中运行函数,我建议使用双通道。这就像传递一个小的布尔球一样。每个函数都有一个它们监听的通道,和另一个通道,在关键部分完成后将球传递给下一个函数。这样,无论何时调用它们,您都可以确保它们始终交替运行。

这种模式还允许您通过f3、f4等来扩展循环。

package main

func f1(do chan bool, next chan bool) {
    //... 一些代码

    <-do // 等待球
    // 关键部分1(CS1)
    //... 关键部分代码
    // 结束关键部分1
    next <- true // 将球传递给下一个函数

    //... 更多代码
}

func f2(do chan bool, next chan bool) {
    //... 一些代码

    <-do
    // 关键部分2(CS2)
    //... 关键部分代码
    // 结束关键部分2
    next <- true

    //... 更多代码
}

func main() {
    cf1 := make(chan bool, 1)
    cf2 := make(chan bool, 1)
    cf1 <- true // 让cf1从球开始

    go f1(cf1, cf2)
    go f2(cf2, cf1)

    // 在这里等待,否则程序会直接退出
}

希望对您有所帮助!

英文:

If you are running the functions in different goroutines, I would suggest dual channels. It is like passing on a little bool-ball. Each function has a channel they listen on, and another channel where they pass on the ball once the critical section is done. Then you can be sure that, no matter when they are called, they will always run alternately.

This pattern also allows you to extend the cycle with f3, f4 ... as well.

package main

func f1(do chan bool, next chan bool) {
        //... some code

      	&lt;-do // Waits for the ball
        // critical section 1 (CS1)
        //... critical section code
        // end criticla section 1
        next &lt;- true // Pass on the ball to the next function

        //... more code
}

func f2(do chan bool, next chan bool) {
        //... some code

        &lt;-do
        // critical section 2 (CS2)
        //... critical section code
        // end criticla section 2
        next &lt;- true

        //... more code
}

func main() {
	cf1 := make(chan bool, 1)
	cf2 := make(chan bool, 1)
	cf1 &lt;- true // Let cf1 start with the ball
	
	go f1(cf1, cf2)
	go f2(cf2, cf1)

	// Wait here, otherwise it will just exit
}

huangapple
  • 本文由 发表于 2013年9月6日 17:29:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/18654457.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定