Go Routine Run as a Thread?

Posted by Henry Du on Monday, October 26, 2020

Go Routine Run as a Thread?

Whether or not a go-routine run as a machine thread is always a question for me, until I finally have a chance to inspect it by gdb. First, We could write a simple go code to have a go func().

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan string)

    go func() {
        fmt.Println(fmt.Sprintf("received the data '%v' from the channel", <-ch))
    }()

    fmt.Println("start to send a test data")
    ch <- "test data"
    // wait for log
    time.Sleep(1 * time.Second)
}

We could inspect the code by gdb to see threads information. As the following debug message shown, when a go program start running, there are several machine threads launched, one for main program, the others are runtime programs.

(gdb) n
11              go func() {
(gdb) info thread
  Id   Target Id         Frame
* 1    LWP 2838 "main"   main.main () at /home/hengdu/go/src/github.com/goplayground/main.go:16
  2    LWP 2842 "main"   runtime.usleep () at /usr/lib/golang/src/runtime/sys_linux_amd64.s:146
  3    LWP 2843 "main"   runtime.futex () at /usr/lib/golang/src/runtime/sys_linux_amd64.s:568
  4    LWP 2844 "main"   runtime.futex () at /usr/lib/golang/src/runtime/sys_linux_amd64.s:568

After code run go func(), there is no new thread launched. Go has a user space processor to maintain a Local Run Queue (LRQ) for all go routines. It simulates kernel space process scheduler to make every go-routine smoothly by using one machine thread.

Therefore, the answer is, Golang has its own user space processor and local run queue for all go routines. It may or may not need to launch the same number of machine threads in terms of number of go-routines.