我的问题是如何安排每个间隔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))
}
}
}
最佳答案
您在循环的每次迭代中都调用computeX
和computeY
。
由于computeX
花费1s,因此for
循环每秒迭代一次,并且在yC
获得值时需要额外的时间。
这意味着您正在go computeY
,t=0s
,t=1s
等处运行t=2s
。
第一个终止于t=10s
,第二个终止于t=11s
,依此类推...
如果要确保一次只安排一个computeX
和computeY
,则需要将主代码更改为以下内容:
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)
}
}
有关代码的其他注意事项:
x
和y
是全局的,并在computeX
和computeY
中分配x
和y
fmt.Println(fmt.Sprintf("..."))
只是fmt.Printf("...\n")
""
,这是默认值关于multithreading - 如何安排运行的非阻塞功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48358137/