我的问题是如何安排每个间隔N运行独立的非阻塞功能。

我最初的方法是在select语句中使用go channel 以非阻塞方式接收值,并在每个函数中使用time.Sleep(N)安排调用。

在下面的代码段中,这仅适用于第一次运行;但是,在第一次调用后,它会继续重复调用computeY(),而不考虑time.Sleep()调用。

    package main

    import (
        "fmt"
        "time"
    )

    var (
        x string = ""
        y string = ""
    )

    func computeY(c chan string) {
        time.Sleep(10 * time.Second)
        fmt.Println("I'm in Y")

        y = "this is Y value"
        c <- y
    }

    func computeX(c chan string) {
        time.Sleep(1 * time.Second)

        x = "this is X value"
        c <- x
    }

    func main() {
        xC := make(chan string)
        yC := make(chan string)

        for {
            go computeX(xC)
            go computeY(yC)

            select {
            case x := <-xC:
                fmt.Println(fmt.Sprintf("X: %v, Y: %v", x, y))
            case y := <-yC:
                fmt.Println(fmt.Sprintf("X: %v, Y: %v", x, y))
            }

        }
    }

最佳答案

您在循环的每次迭代中都调用computeXcomputeY

由于computeX花费1s,因此for循环每秒迭代一次,并且在yC获得值时需要额外的时间。

这意味着您正在go computeYt=0st=1s等处运行t=2s
第一个终止于t=10s,第二个终止于t=11s,依此类推...

如果要确保一次只安排一个computeXcomputeY,则需要将主代码更改为以下内容:

    go computeX(xC)
    go computeY(yC)
    for {
        select {
        case x = <-xC:
            fmt.Printf("Finished computeX: X: %v, Y: %v\n", x, y)
            go computeX(xC)
        case y = <-yC:
            fmt.Printf("Finished computeY: X: %v, Y: %v\n", x, y)
            go computeY(yC)
        }
    }

有关代码的其他注意事项:
  • xy是全局的,并在computeXcomputeY中分配
  • 您的 channel 读取影子xy
  • fmt.Println(fmt.Sprintf("..."))只是fmt.Printf("...\n")
  • 不需要将字符串初始化为"",这是默认值
  • 关于multithreading - 如何安排运行的非阻塞功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48358137/

    10-15 23:57