python进程间通信--信号Signal
信号signal 是python进程间通信多种机制中的其中一种机制。可以对操作系统进程的控制,当进程中发生某种原因而中断时,可以异步处理这个异常。 信号通过注册的方式‘挂’在一个进程中,并且不会阻塞该进程的运行。一个进程一旦接收到其他进程(可能是应用中的其他进程,也可能使操作系统中的进程)发送的信号就会打断原来的程序执行流程来处理这个信号。 名词理解: 异步: 程序在执行中利用内核功能帮助完成必要的辅助操作,不影响应用层持续执行 注意: 这里的同步和异步机制是相对多进程而言的。 在多个进程中通信的机制中,只有singal是异步执行的,另外python进程间通信的机制还有pipe(管道),queue(队列),value(共享空间)等等。 signal可以用在什么地方? siganl的应用: 1. 故障定位技术(进程的底层故障,例如进程突然中断和一些可能性较小的故障) 2. 对进程的流程控制?
(1)os.kill(pid,sig) 发送一个信号给某个进程 参数解析: pid 指定发送信号的进程号 sig? 要发送的信号代号(需要通过signal模块获取) (2)signal.alarm(sec)? 非阻塞函数 设置时钟信号,在一定时间后给自身发送一个SIGALRM信号 原理: 时钟的创建是进程交由操作系统内核(kernal)帮助创建的 时钟和进程之间是异步执行的,当时钟到时,内核会发送信号给进程,进程接收信号进行相应的响应操作。 注意:如果设置多个时钟,后面的时钟会覆盖前面的时钟,一个进程只有一个挂起的时钟。 (3)signal.pause() 阻塞进程,等待一个信号.当接收到信号时就会停止阻塞 例如:等待signal()函数的发送 (4)signal.signal(sig,handler) 这是信号中最关键的一个方法,用于声明一个信号。当进程运行过程中出现故障异常或者需要进程间通信时,由操作系统内核中的进程或者应用中的进程发出处理信号,通知注册了信号的进程进行处理。 signal.signal(sig,handler) 参数理解: sig 要处理的信号名称 handler 信号处理方法?? 可选值: SIG_DFL?? ?表示默认方法处理 ?????????????? SIG_IGN??? 表示忽略这个信号(一般为了避免父进程和子进程的互相干扰而使用) ?????????????? handler?????? 自定义回调函数 ? 自定义回调函数handler: 这个是当用于在进程捕捉到其他进程发送的信号时调用的函数,当此函数返回时,进程继续继续按原来的逻辑顺序执行。此函数在定义时python普通函数的定义没有区别。函数名不一定是handler,但作为作为参数传入signal()方法的参数名一定是与定义handler函数的函数相同。 def? handler(signum,frame): ??? do? something… ?1)sig :接收到的信号编号,signal模块内部定义了一些常用的内核信号,并为它们进行了编号。 例如: windows操作系统下 SIGNALINT编号为2 >>>signal.SIGINT SIGBREAK编号为21 >>>signal.SIGBREAK 注意:windows操作系统没有SIGUSR1和SIGUSR2这两个型号类型,linux操作系统才有。 2)?frame:信号结构对象(可以通过结构对象查看信号信息,基本不用) signal函数实际上是一个异步的回调函数,只要执行了该函数,则进程任意时候接收到相应信号都会处理。?这里的异步就是上文提到的异步机制,是计算机内核程序与本进程间同时运行,互相不干扰的一种机制,对于进程的正常执行有着关键的作用。这种异步机制在任何后端编程语言中都是存在的,只不过实现的方式和细节不一样而已。 singnal怎么用? 一般信号signal是在需要检测异常的程序的开头就定义好了,程序顺序向下运行时,一旦捕获到操作系统发出的signal或者其他进程发出的signal,马上就会停止当前的程序运行状态,去处理捕获到的signal。 <span style="color: #0000ff">print(<span style="color: #800000">"<span style="color: #800000">The process's PID is:<span style="color: #800000">"<span style="color: #000000">,os.getpid())
<span style="color: #0000ff">def<span style="color: #000000"> handle_signal(signum,frame): <span style="color: #0000ff">print(<span style="color: #800000">'<span style="color: #800000">Received and handle:<span style="color: #800000">'<span style="color: #000000">,signum) <span style="color: #008000">#<span style="color: #008000">注册信号处理程序 <span style="color: #0000ff">print(<span style="color: #800000">"<span style="color: #800000">The process's PID is:<span style="color: #800000">"<span style="color: #000000">,os.getpid()) <span style="color: #0000ff">while<span style="color: #000000"> True: >>> os.kill(7094>>> os.kill(7094,signal.SIGUSR2)
结果: 17 12:19:26 201817 12:19:28 2018 handle: 1017 12:19:30 2018Waiting...
Sat Nov 17 12:22:21 2018<span style="color: #000000"> Received <span style="color: #0000ff">and handle: 12<span style="color: #000000"> Waiting... Sat Nov 17 12:22:23 2018
<span style="color: #0000ff">print(<span style="color: #800000">"<span style="color: #800000">The process's PID is:<span style="color: #800000">"<span style="color: #000000">,os.getpid())
<span style="color: #0000ff">def<span style="color: #000000"> handle_signal(signum,signum)
<span style="color: #0000ff">def<span style="color: #000000"> handle_interrupt(signum,frame):
<span style="color: #0000ff">print(<span style="color: #800000">'<span style="color: #800000">Receive keyboard interrupt<span style="color: #800000">'<span style="color: #000000">) sys.exit(0) <span style="color: #008000">#<span style="color: #008000">退出进程 <span style="color: #008000">#<span style="color: #008000">注册信号处理程序 <span style="color: #0000ff">while<span style="color: #000000"> True: 终端输入: >>> os.kill(7625,signal.SIGINT) 会退出进程 如果注册函数改为 signal.signal(signal.SIGINT,signal.SIG_IGN) 则会忽略终端发出的SIGINT
(signal.signal(signal.SIGALRM,handle_signal)
signal.alarm(3<span style="color: #000000">) <span style="color: #0000ff">while<span style="color: #000000"> True: <span style="color: #0000ff">print<span style="color: #000000">(time.ctime()) time.sleep(1) 结果: Sat Nov 17 13:21:51 201817 13:21:52 201817 13:21:53 2018 up! 14
附录: windows下的sig信号类型 >>> dir(signal) ['CTRL_BREAK_EVENT','CTRL_C_EVENT','Handlers','NSIG','SIGABRT','SIGBREAK','SIGFPE','SIGILL','SIGINT','SIGSEGV','SIGTERM','SIG_DFL','SIG_IGN','Signals','_IntEnum','__builtins__','__cached__','__doc__','__file__','__loader__','__name__','__package__','__spec__','_enum_to_int','_int_to_enum','_signal','default_int_handler','getsignal','set_wakeup_fd','signal'] linux下的sig信号类型 >>> dir(signal) ['ITIMER_PROF','ITIMER_REAL','ITIMER_VIRTUAL','ItimerError','SIGALRM','SIGBUS','SIGCHLD','SIGCLD','SIGCONT','SIGHUP','SIGIO','SIGIOT','SIGKILL','SIGPIPE','SIGPOLL','SIGPROF','SIGPWR','SIGQUIT','SIGRTMAX','SIGRTMIN','SIGSTOP','SIGSYS','SIGTRAP','SIGTSTP','SIGTTIN','SIGTTOU','SIGURG','SIGUSR1','SIGUSR2','SIGVTALRM','SIGWINCH','SIGXCPU','SIGXFSZ','alarm','getitimer','pause','setitimer','siginterrupt','signal'] 常用信号类型解析 SIGHUP?? 断开连接 SIGINT??? ctrl-C SIGUIT??? ctrl- SIGTSTP?? ctrl-z SIGKILL??? 终止进程且不能被处理 SIGSTOP?? 暂停进程且不能被处理 SIGALRM?? 时钟进程 SIGCHLD?? 子进程状态改变发送给父进程信息号(但一般父进程不会处理) 参考文章: https://www.cnblogs.com/xautxuqiang/p/5339602.html https://www.cnblogs.com/madsnotes/articles/5688681.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |