Go با مثال: سیگنال‌ها

گاهی می‌خواهیم برنامه‌های Go ما سیگنال‌های یونیکس را هوشمندانه مدیریت کنند. برای مثال، ممکن است بخواهیم یک سرور با دریافت SIGTERM به‌آرامی (gracefully) خاموش شود، یا یک ابزار خط فرمان با دریافت SIGINT پردازش ورودی را متوقف کند. این یک روش مدرن برای مدیریت سیگنال‌ها با context است.

package main
import (
    "context"
    "fmt"
    "os/signal"
    "syscall"
)

signal.NotifyContext یک context برمی‌گرداند که با رسیدن یکی از سیگنال‌های فهرست‌شده لغو می‌شود.

func main() {
    ctx, stop := signal.NotifyContext(
        context.Background(), syscall.SIGINT, syscall.SIGTERM)
    defer stop()

برنامه اینجا منتظر می‌ماند تا یکی از سیگنال‌های تنظیم‌شده دریافت شود.

    fmt.Println("awaiting signal")
    <-ctx.Done()

context.Cause گزارش می‌دهد که چرا context لغو شده. برای لغوی که با سیگنال رخ داده، شامل مقدار سیگنال هم هست.

    fmt.Println()
    fmt.Println(context.Cause(ctx))
    fmt.Println("exiting")
}

وقتی این برنامه را اجرا کنیم، منتظر یک سیگنال مسدود می‌ماند. با زدن ctrl-C (که ترمینال آن را به شکل ^C نشان می‌دهد) می‌توانیم سیگنال SIGINT بفرستیم؛ در نتیجه برنامه دلیل لغو را چاپ می‌کند و خارج می‌شود.

$ go run signals.go
awaiting signal
^C
interrupt signal received
exiting

مثال بعدی: .