Black Lives Matter. Support the Equal Justice Initiative.

Package signal

import "os/signal"
Overview
Index
Examples
Subdirectories

Overview ▾

封装信号实现对输入信号的访问.

信号主要用于类Unix系统. 有关在Windows和Plan 9上使用此软件包的信息,请参见下文.

Types of signals

信号SIGKILL和SIGSTOP可能不会被程序捕获,因此不会受到此程序包的影响.

同步信号是由程序执行中的错误触发的信号:SIGBUS,SIGFPE和SIGSEGV. 这些仅在由程序执行引起时才被认为是同步的,而不是在使用os.Process.Kill或kill程序或某些类似机制发送时才被视为同步. 通常,除以下讨论的内容外,Go程序会将同步信号转换为运行时紧急情况.

其余信号是异步信号. 它们不是由程序错误触发的,而是从内核或其他程序发送的.

在异步信号中,当程序丢失其控制端子时,将发送SIGHUP信号. 当控制终端上的用户按下中断字符时,将发送SIGINT信号,默认情况下为^ C(Control-C). 当控制终端上的用户按下退出字符(默认情况下为^ \)时,将发送SIGQUIT信号. 通常,您可以通过按^ C导致程序简单退出,并可以通过按^ \使其退出堆栈堆栈.

Default behavior of signals in Go programs

By default, a synchronous signal is converted into a run-time panic. A SIGHUP, SIGINT, or SIGTERM signal causes the program to exit. A SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGSTKFLT, SIGEMT, or SIGSYS signal causes the program to exit with a stack dump. A SIGTSTP, SIGTTIN, or SIGTTOU signal gets the system default behavior (these signals are used by the shell for job control). The SIGPROF signal is handled directly by the Go runtime to implement runtime.CPUProfile. Other signals will be caught but no action will be taken.

如果Go程序在忽略SIGHUP或SIGINT的情况下启动(信号处理程序设置为SIG_IGN),则它们将保持忽略状态.

如果Go程序以非空的信号掩码启动,通常会很荣幸. 但是,某些信号被显式解除阻塞:同步信号SIGILL,SIGTRAP,SIGSTKFLT,SIGCHLD,SIGPROF,以及在GNU / Linux上,信号32(SIGCANCEL)和33(SIGSETXID)(glibc在内部使用了SIGCANCEL和SIGSETXID). 由os.Exec或os / exec程序包启动的子进程将继承修改后的信号掩码.

Changing the behavior of signals in Go programs

该软件包中的功能允许程序更改Go程序处理信号的方式.

通知禁用一组给定异步信号的默认行为,而是通过一个或多个已注册通道传递它们. 具体来说,它适用于信号SIGHUP,SIGINT,SIGQUIT,SIGABRT和SIGTERM. 它也适用于作业控制信号SIGTSTP,SIGTTIN和SIGTTOU,在这种情况下,不会发生系统默认行为. 它也适用于其他不引起作用的信号:SIGUSR1,SIGUSR2,SIGPIPE,SIGALRM,SIGCHLD,SIGCONT,SIGURG,SIGXCPU,SIGXFSZ,SIGVTALRM,SIGWINCH,SIGIO,SIGPWR,SIGSYS,SIGINFO,SIGTHR,SIGWAITING,SIGLAIZE,SIGL SIGTHAW,SIGLOST,SIGXRES,SIGJVM1,SIGJVM2以及系统上使用的任何实时信号. 请注意,并非所有这些信号在所有系统上都可用.

如果程序是在忽略SIGHUP或SIGINT的情况下启动的,并且为任一信号调用了Notify,则将为该信号安装信号处理程序,并且将不再忽略该信号处理程序. 如果稍后再对该信号调用"重置"或"忽略",或者在传递给该信号的"通知"的所有通道上调用"停止",则该信号将再次被忽略. 重置将恢复信号的系统默认行为,而忽略将导致系统完全忽略信号.

如果程序以非空信号掩码启动,则如上所述,某些信号将被显式解除阻塞. 如果为阻止信号而调用通知,则将取消阻止. 如果稍后再对该信号调用"重置",或者在传递给该信号的"通知"的所有通道上调用"停止",则该信号将再次被阻止.

SIGPIPE

当Go程序写入中断的管道时,内核将引发SIGPIPE信号.

如果程序尚未调用Notify来接收SIGPIPE信号,则其行为取决于文件描述符号. 在文件描述符1或2(标准输出或标准错误)上写入损坏的管道将导致程序以SIGPIPE信号退出. 在其他文件描述符上写入损坏的管道将不会对SIGPIPE信号执行任何操作,并且写入将失败并显示EPIPE错误.

如果程序已调用Notify来接收SIGPIPE信号,则文件描述符号无关紧要. SIGPIPE信号将被传递到通知通道,并且写入将失败并出现EPIPE错误.

这意味着默认情况下,命令行程序的行为类似于典型的Unix命令行程序,而其他程序在写入封闭的网络连接时不会因SIGPIPE崩溃.

Go programs that use cgo or SWIG

在包含非Go代码(通常是使用cgo或SWIG访问的C / C ++代码)的Go程序中,Go的启动代码通常会首先运行. 在非Go启动代码运行之前,它将按Go运行时的预期配置信号处理程序. 如果非Go启动代码希望安装自己的信号处理程序,则必须采取某些步骤才能使Go正常运行. 本节记录了这些步骤,并且非Go代码可以在Go程序上对信号处理程序设置进行整体更改. 在极少数情况下,非Go代码可能会在Go代码之前运行,在这种情况下,下一节也适用.

如果Go程序调用的非Go代码没有更改任何信号处理程序或掩码,则其行为与纯Go程序相同.

If the non-Go code installs any signal handlers, it must use the SA_ONSTACK flag with sigaction. Failing to do so is likely to cause the program to crash if the signal is received. Go programs routinely run with a limited stack, and therefore set up an alternate signal stack. Also, the Go standard library expects that any signal handlers will use the SA_RESTART flag. Failing to do so may cause some library calls to return "interrupted system call" errors.

如果非Go代码为任何同步信号(SIGBUS,SIGFPE,SIGSEGV)安装了信号处理程序,则它应记录现有的Go信号处理程序. 如果在执行Go代码时发生这些信号,则应调用Go信号处理程序(可以通过查看传递给信号处理程序的PC来确定在执行Go代码时是否发生信号). 否则,某些Go运行时恐慌将不会按预期发生.

如果非Go代码为任何异步信号安装了信号处理程序,则它可能会选择调用Go信号处理程序,也可能不会调用它. 自然,如果它不调用Go信号处理程序,则不会发生上述的Go行为. 特别是这可能与SIGPROF信号有关.

非Go代码不应在Go运行时创建的任何线程上更改信号掩码. 如果非Go代码启动了自己的新线程,则可以根据需要设置信号掩码.

如果非Go代码启动一个新线程,更改信号掩码,然后在该线程中调用Go函数,则Go运行时将自动取消阻止某些信号:同步信号,SIGILL,SIGTRAP,SIGSTKFLT,SIGCHLD,SIGPROF,SIGCANCEL和SIGSETXID. 当执行功能返回时,将恢复非执行信号屏蔽.

如果在未运行Go代码的非Go线程上调用Go信号处理程序,则该处理程序通常将信号转发到非Go代码,如下所示. 如果信号是SIGPROF,则Go处理程序不执行任何操作. 否则,Go处理程序将删除自身,解除阻塞信号,然后再次引发信号,以调用任何非Go处理程序或默认系统处理程序. 如果程序没有退出,则Go处理程序将重新安装自身并继续执行程序.

Non-Go programs that call Go code

当使用-buildmode = c-shared之类的选项构建Go代码时,它将作为现有非Go程序的一部分运行. 启动Go代码时,非Go代码可能已经安装了信号处理程序(在使用cgo或SWIG的异常情况下也可能会发生;在这种情况下,此处的讨论适用). 对于-buildmode = c-archive,Go运行时将在全局构造函数时初始化信号. 对于-buildmode = c-shared,当加载共享库时,Go运行时将初始化信号.

如果Go运行时看到SIGCANCEL或SIGSETXID信号的现有信号处理程序(仅在GNU / Linux上使用),它将打开SA_ONSTACK标志,否则保留信号处理程序.

对于同步信号和SIGPIPE,Go运行时将安装信号处理程序. 它将保存任何现有的信号处理程序. 如果在执行非Go代码时同步信号到达,则Go运行时将调用现有的信号处理程序,而不是Go信号处理程序.

默认情况下,使用-buildmode = c-archive或-buildmode = c-shared构建的Go代码不会安装任何其他信号处理程序. 如果存在现有的信号处理程序,则Go运行时将打开SA_ONSTACK标志,否则将保留信号处理程序. 如果为异步信号调用Notify,则将为该信号安装Go信号处理程序. 如果稍后再对该信号调用Reset,则将重新安装该信号的原始处理,以恢复non-Go信号处理程序(如果有).

在没有-buildmode = c-archive或-buildmode = c-shared的情况下构建的Go代码将为上面列出的异步信号安装信号处理程序,并保存任何现有的信号处理程序. 如果将信号传递到non-Go线程,则它将如上所述执行操作,除了如果存在现有的non-Go信号处理程序,该处理程序将在发出信号之前安装.

Windows

在Windows上,^ C(Control-C)或^ BREAK(Control-Break)通常会导致程序退出. 如果为os.Interrupt调用了Notify,则^ C或^ BREAK将导致os.Interrupt在通道上发送,并且程序不会退出. 如果调用Reset或在传递给Notify的所有通道上调用Stop,则将恢复默认行为.

此外,如果调用了Notify,并且Windows将CTRL_CLOSE_EVENT,CTRL_LOGOFF_EVENT或CTRL_SHUTDOWN_EVENT发送到该进程,则Notify将返回syscall.SIGTERM. 与Control-C和Control-Break不同,当收到CTRL_CLOSE_EVENT,CTRL_LOGOFF_EVENT或CTRL_SHUTDOWN_EVENT时,Notify不会更改进程行为-除非退出,否则该进程仍将终止. 但是接收syscall.SIGTERM将使进程有机会在终止之前进行清理.

Plan 9

在计划9上,信号的类型为syscall.Note,这是一个字符串. 使用syscall.Not调用Notify时,该字符串作为注释发布时,该值将在通道上发送.

func Ignore 1.5

func Ignore(sig ...os.Signal)

忽略将忽略提供的信号. 如果程序接收到它们,则不会发生任何事情. 忽略将撤消先前为提供的信号进行通知的任何调用的影响. 如果未提供任何信号,则所有输入信号都将被忽略.

func Ignored 1.11

func Ignored(sig os.Signal) bool

被忽略的报告当前是否忽略sig.

func Notify

func Notify(c chan<- os.Signal, sig ...os.Signal)

通知使包裹信号将传入信号中继到c. 如果未提供信号,则所有输入信号都将中继到c. 否则,仅提供信号即可.

包信号将不会阻止发送到c:调用方必须确保c有足够的缓冲区空间以跟上预期的信号速率. 对于仅通知一个信号值的通道,大小为1的缓冲区就足够了.

允许在同一通道上多次调用"通知":每次调用都会扩展发送到该通道的信号集. 从设备中删除信号的唯一方法是调用Stop.

允许使用不同的通道和相同的信号多次调用"通知":每个通道独立接收输入信号的副本.

Example

示例(所有信号)

func Reset 1.5

func Reset(sig ...os.Signal)

重置将取消先前调用所提供信号的通知的影响. 如果未提供任何信号,则将重置所有信号处理程序.

func Stop 1.1

func Stop(c chan<- os.Signal)

停止会使包装信号停止将传入信号中继到c. 它取消使用c进行的所有先前对Notify的调用的影响. 当Stop返回时,可以保证c不会再收到信号.

Subdirectories

Name Synopsis
..

by  ICOPY.SITE