When we write a simple Golang program test
, like
1 | package main |
How Golang to implement these functions?
In this blog, I simply analyze the timer that is used for Sleep()
function of Golang v1.12.
TLDR
Golang Sleep()
function utilizes hrtimer
to set timeout of sleep.
Full article
In Linux POSIX (Portable Operating System Interface), sleep
function has been implemented. You can try
1 | $ sleep 1 |
in shell for sleeping one second, which is implemented by linux timer nanosleep
.
However, Golang does not use timer for its Sleep()
directly. If you check code in go/src/time/sleep.go
, you’ll find that timer is not implemented in this file. Instead, it is implemented in go/src/runtime/time.go
. In the function timeSleep(ns int64)
,
1 | func timeSleep(ns int64) { |
before line 17, function is creating a timer. In line 17, it locks timer. So, Sleep()
sets up timer by locking a resource ns
nanoseconds. If we use strace
to run a go application,
1 | $ strace ./test |
Sleep()
call futex function to sleep.
In the go/src/runtime/lock_futex.go
, lock
function
1 | func lock(l *mutex) { |
line 57 calls futexsleep
.
In go/src/runtime/os_linux.go
, function futexsleep
is defined as to call futex function of linux.
So far, we can know that Golang utilize Linux futex
function to set timer for Sleep()
function.
In Linux , futex
is implemented in linux/kernel/futex.c
. hrtimer
is used as timer of futex
. hrtimer
is a high-resolution timer compared with the other timers (itimers
, POSIX timers
,nanosleep
,precise in-kernel timing
).
In summary, when we call Sleep()
function in Golang,
App calls sleep of Golang -> Golang calls futex of Linux -> futex utilizes hrtimer to be timer.