Open
Description
What version of Go are you using (go version
)?
go version go1.10.1 linux/amd64
Does this issue reproduce with the latest release?
Yes (1.10.2
).
What operating system and processor architecture are you using (go env
)?
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/bas/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/bas/go"
GORACE=""
GOROOT="/usr/lib/go-1.10"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go-1.10/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build723289083=/tmp/go-build -gno-record-gcc-switches"
What did you do?
The following Go program calls time.Sleep
the number of times given as a commandline argument.
package main
import (
"os"
"strconv"
"time"
)
var max int
func main() {
max, _ = strconv.Atoi(os.Args[1])
n := 0
for {
time.Sleep(time.Second / 100)
n += 1
if n >= max {
return
}
}
}
If track the number of sys calls using strace -f -c
, we find
bas@fourier2:~/gosleeptest$ strace -c -f ./gosleeptest 1
strace: Process 3115 attached
strace: Process 3114 attached
strace: Process 3116 attached
strace: Process 3117 attached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 8 mmap
0.00 0.000000 0 1 munmap
0.00 0.000000 0 114 rt_sigaction
0.00 0.000000 0 14 rt_sigprocmask
0.00 0.000000 0 4 clone
0.00 0.000000 0 1 execve
0.00 0.000000 0 10 sigaltstack
0.00 0.000000 0 5 arch_prctl
0.00 0.000000 0 9 gettid
0.00 0.000000 0 8 1 futex
0.00 0.000000 0 1 sched_getaffinity
0.00 0.000000 0 1 readlinkat
0.00 0.000000 0 22 pselect6
------ ----------- ----------- --------- --------- ----------------
100.00 0.000000 198 1 total
bas@fourier2:~/gosleeptest$ strace -c -f ./gosleeptest 10
strace: Process 3919 attached
strace: Process 3918 attached
strace: Process 3917 attached
strace: Process 3927 attached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 8 mmap
0.00 0.000000 0 1 munmap
0.00 0.000000 0 114 rt_sigaction
0.00 0.000000 0 14 rt_sigprocmask
0.00 0.000000 0 2 sched_yield
0.00 0.000000 0 4 clone
0.00 0.000000 0 1 execve
0.00 0.000000 0 10 sigaltstack
0.00 0.000000 0 5 arch_prctl
0.00 0.000000 0 9 gettid
0.00 0.000000 0 74 12 futex
0.00 0.000000 0 1 sched_getaffinity
0.00 0.000000 0 1 readlinkat
0.00 0.000000 0 69 pselect6
------ ----------- ----------- --------- --------- ----------------
100.00 0.000000 313 12 total
bas@fourier2:~/gosleeptest$ strace -c -f ./gosleeptest 100
strace: Process 4491 attached
strace: Process 4490 attached
strace: Process 4489 attached
strace: Process 4532 attached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
89.01 0.043330 82 530 104 futex
9.76 0.004751 21 228 pselect6
0.27 0.000131 1 114 rt_sigaction
0.23 0.000114 23 5 arch_prctl
0.19 0.000091 9 10 sigaltstack
0.18 0.000086 10 9 gettid
0.13 0.000061 4 14 rt_sigprocmask
0.07 0.000035 4 8 mmap
0.07 0.000033 33 1 readlinkat
0.03 0.000017 4 4 clone
0.03 0.000017 17 1 execve
0.02 0.000009 9 1 munmap
0.01 0.000003 3 1 sched_getaffinity
------ ----------- ----------- --------- --------- ----------------
100.00 0.048678 926 104 total
What did you expect to see?
A single time.Sleep
should use approximately one syscall. (Python's time.sleep
does only use one syscall, for instance.)
What did you see instead?
Approximately seven sys calls per time.Sleep
. As a consequence, the go process also uses quite a bit of CPU time per time.Sleep
: 500us (compared to 13us for Python's time.sleep
).
Notes
I encountered this issue while debugging unexpectedly high idle CPU usage by wireguard-go
.