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

默认情况下,同步信号会转换为运行时紧急情况. SIGHUP,SIGINT或SIGTERM信号导致程序退出. SIGQUIT,SIGILL,SIGTRAP,SIGABRT,SIGSTKFLT,SIGEMT或SIGSYS信号会导致程序退出堆栈转储. SIGTSTP,SIGTTIN或SIGTTOU信号获得系统默认行为(shell将这些信号用于作业控制). SIGPROF信号由Go运行时直接处理以实现runtime.CPUProfile. 其他信号将被捕获,但不会采取任何措施.

If the Go program is started with either SIGHUP or SIGINT ignored (signal handler set to SIG_IGN), they will remain ignored.

如果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,则将恢复默认行为.

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