golangの日記

Go言語を中心にプログラミングについてのブログ

ゴルーチンを使ってシグナルを受け取ると signal: urgent I/O condition が飛んでくる

golang.png


Go 1.14 からゴルーチンの切り替えにシグナル(SIGURG)が使われるようになったらしく、Linuxではシグナルを受け取る処理で signal: urgent I/O condition が飛んでくる。

blog.lufia.org





package main

import (
    "fmt"
    "os"
    "os/signal"
    "syscall"
)

func receiveSignal() {
    ch := make(chan os.Signal)
    signal.Notify(ch)
    for {
        switch signal := <-ch; signal {
        case syscall.SIGURG:
            fmt.Println("signal:", signal.String())
        default:
            fmt.Println("signal:", signal.String())
            os.Exit(0)
        }
    }
}

func main() {
    go receiveSignal()

    for {
    }
}


上記のコードを実行すると signal: urgent I/O condition が出力され続ける。

signal: urgent I/O condition
signal: urgent I/O condition
signal: urgent I/O condition
signal: urgent I/O condition
signal: urgent I/O condition
signal: urgent I/O condition
signal: urgent I/O condition


signal.Ignore を使って無視すればいいけど、Windowsには syscall.SIGURG はないので、同じコードをLinuxとWindowsで使うことを考えて syscall.Signal(0x17) で無視することにした。

ch := make(chan os.Signal)
signal.Notify(ch)
signal.Ignore(syscall.Signal(0x17))
signal := <-ch
fmt.Println("signal:", signal.String())
os.Exit(0)