いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-219 (Go が 内部で利用しているスレッド数を表示するサンプル)

概要

Goで実際に利用されているOSのスレッド数を知りたいときはなかなか無いと思いますが、知識としてしっておくといいかもしれないですね。

以下のサンプルでは、変化をわかりやすくするために、一つのゴルーチン毎に runtime.LockOSThread() を呼び出して、そのゴルーチンが動くスレッドを束縛するようにしています。

/*
   Goが内部で利用しているスレッド数を表示するサンプルです。

   結果は例えば以下のようになります。(結果は環境によって異なります。)

       $ go install github.com/go-task/task/v3/cmd/task@latest
       $ go install honnef.co/go/tools/cmd/staticcheck@latest
       $ task
       task: [run] go fmt
       task: [run] go vet ./...
       task: [run] staticcheck ./...
       task: [run] go run main.go
       [BEFORE] lock-thread=false      thread count=5
       [AFTER ] lock-thread=false      thread count=5
       [BEFORE] lock-thread=true       thread count=5
       [AFTER ] lock-thread=true       thread count=15

   REFERENCES:
       - https://blog.rahuldev.in/how-to-implement-concurrency-and-parallelism-in-go
*/
package main

import (
    "fmt"
    "runtime"
    "runtime/pprof"
    "sync"
    "time"
)

func fn(lockThread bool, wg *sync.WaitGroup) {
    defer wg.Done()

    if lockThread {
        runtime.LockOSThread()
        defer runtime.UnlockOSThread()
    }

    time.Sleep(1 * time.Second)
}

func main() {
    const (
        NUM_GOROUTINE = 10
    )

    var (
        threadProfile = pprof.Lookup("threadcreate")
    )

    for _, lockThread := range []bool{false, true} {
        var (
            wg sync.WaitGroup
        )

        fmt.Printf("[BEFORE] lock-thread=%v\tthread count=%d\n", lockThread, threadProfile.Count())

        wg.Add(NUM_GOROUTINE)
        for i := 0; i < NUM_GOROUTINE; i++ {
            go fn(lockThread, &wg)
        }
        wg.Wait()

        fmt.Printf("[AFTER ] lock-thread=%v\tthread count=%d\n", lockThread, threadProfile.Count())
    }
}

go-taskのタスクファイルは以下。

version: '3'

tasks:
  default:
    cmds:
      - task: run
  run:
    cmds:
      - go fmt
      - go vet ./...
      - staticcheck ./...
      - go run main.go

実行すると以下のようになります。

gitpod /workspace/try-golang (master) $ task -d examples/singleapp/pprof_thread_count/
task: [run] go fmt
task: [run] go vet ./...
task: [run] staticcheck ./...
task: [run] go run main.go
[BEFORE] lock-thread=false      thread count=5
[AFTER ] lock-thread=false      thread count=5
[BEFORE] lock-thread=true       thread count=5
[AFTER ] lock-thread=true       thread count=15

参考情報


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。