谷歌go goroutine的中断模式(速度问题) [英] interrupt pattern for google go goroutine (speed issue)
问题描述
我运行一个goroutine来增加一个计数器,这个计数器可以被命令行输入t \ n中断。
在中选择
语句,如果我选择使用 default:
,则计数器变量 j
会前转。这对我来说似乎很正常。然而,如果我选择使用 case< -time.After(100 * time.Microsecond):
,计数器 j
仅在一秒内增加到60个左右,而不是10,000个。
事实上,无论我在 time.After()
中输入什么值,我只能得到大约60Hz的速率运行通过选择
语句。
为什么?
<$ p
fmt
os
字符串
$ b $时间
)
func main(){
message:= make(chan string)
check check_input(message)
work_loop(message)
$ b $ func work_loop(消息chan字符串){
// var j [] [] int
var j int
t0:= time.Now ()
循环:
用于{
select {
case msg:=< -message:
如果msg ==terminate{
/ /fmt.Println(\"end task)
t1:= time.Now()
fmt.Println(j)
fmt.Println(total duration:,t1.Sub( t0))
break循环
}
大小写< -time.After(100 * time.Microsecond):
//默认:
//在这里工作
j + = 1
fmt.Println(j)
break
}
}
//fmt.Println(\"exit work loop)
}
func check_input(msg chan string){
reader:= bufio.NewReader(os.Stdin )
for {
line,err:= reader.ReadString('\\\
')
if err!= nil {
//您可以在这里查看if err == io.EOF
break
}
if strings.TrimSpace(line)==t{
msg< - terminate
}
}
}
它与 time.Timer
的精度有关。查看 time.After
:
$ b
[...]的文档相当于NewTimer(d).C。
和 time.NewTimer $ c的文档
$ b
NewTimer创建一个新的Timer,它将在至少之后的频道上发送当前时间。持续时间d。
(强调我的)
原因是 NewTimer
委托给一个运行时(操作系统相关)定时器,使得这个定时器的行为依赖于底层操作系统(以及Go集成的实现)。通常,我的经验是,亚毫秒粒度对任何语言都没有良好的跨平台支持,尤其是在Windows XP上 。 。
I run a goroutine to increment a counter, which can be interrupted by command line input "t\n"
In the select
statement, if I choose to use default:
, the counter variable j
flies forword. That seems normal to me.
However, if I choose to use case <-time.After(100*time.Microsecond):
, the counter j
only adds up to 60 or so in one second, instead of 10,000.
In fact no matter what value I put in time.After()
, I only get about 60Hz rate running through the select
statement.
Why?
package main
import (
"bufio"
"fmt"
"os"
"strings"
"time"
)
func main() {
message := make(chan string)
go check_input(message)
work_loop(message)
}
func work_loop(message chan string) {
//var j [][]int
var j int
t0:=time.Now()
Loop:
for {
select {
case msg := <-message:
if msg == "terminate" {
//fmt.Println("end task")
t1:=time.Now()
fmt.Println(j)
fmt.Println("total duration:", t1.Sub(t0))
break Loop
}
case <-time.After(100 * time.Microsecond):
//default:
//do work here
j += 1
fmt.Println(j)
break
}
}
//fmt.Println("exit work loop")
}
func check_input(msg chan string) {
reader := bufio.NewReader(os.Stdin)
for {
line, err := reader.ReadString('\n')
if err != nil {
// You may check here if err == io.EOF
break
}
if strings.TrimSpace(line) == "t" {
msg <- "terminate"
}
}
}
It has to do with the precision of time.Timer
. Looking at the documentation of time.After
:
[...] It is equivalent to NewTimer(d).C.
and the documentation of time.NewTimer
:
NewTimer creates a new Timer that will send the current time on its channel after at least duration d.
(emphasis mine)
The reason for this is that NewTimer
delegates to a runtime (OS-dependent) timer,making the behavior of this timer dependent on the underlying OS (and the implementation of the Go integration).
In general, it is my experience that sub-millisecond granularity does not have good cross-platform support in any language, especially on Windows XP.
这篇关于谷歌go goroutine的中断模式(速度问题)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!