https://blog.csdn.net/qq_20218109/article/details/52078076
避免僵尸进程的三种方法
https://blog.csdn.net/u010872995/article/details/46311815
python简单程序使用signal模块处理僵死进程
https://blog.csdn.net/u011068702/article/details/54409273
linux c之wait和waitpid函数的用法和总结
https://www.cnblogs.com/gengyi/p/8680849.html 利用信号signal处理僵尸进程
1 signal处理僵尸进程的基于语法
利用信号signal处理僵尸进程的方法:signal(SIGCHLD,SIG_IGN),该方法也是第三种处理僵尸进程的方法。
SIGCHLD:子进程状态改变后产生此信号,父进程需要调用一个wait函数以确定发生了什么。
1)SIG_IGN:信号被无视(ignore)或忽略,在该状态下,调用进程的子进程将不产生僵尸进程。
该种模式下的子进程状态信息会被丢弃,也就是自动回收,所以不会产生僵尸进程,但问题也就来了,若调用wait、waitpid函数时无法捕捉到子进程状态信息了,也就会阻塞到所有的子进程结束;并返回错误ECHILD,也就是没有子进程等待。
2)SIG_DFL:进程采用默认(default)行为处理,而默认的处理方式是不理会该信号,但也不会丢弃子进程的状态,所以此时不用wait、waitpid对其子进程进行状态信息回收,则会产生僵尸进程。
2 unix中僵尸进程的含义
凡是父进程没有调用wait函数获得子进程终止状态的子进程在终止之后都是僵尸进程,在这个概念中关键一点就是父进程是否调用了wait函数。
3 SIGCHLD信号
简单地说,子进程退出时父进程会收到一个SIGCHLD信号,默认的处理方式是忽略该信号,而常规的做法是在这个信号处理函数中调用wait函数获取子进程的退出状态。
4、既然在SIGCHLD信号的处理函数中要调用wait函数族,为什么有了wait函数族还需要使用SIGCHLD信号?
unix中的信号处理是采用异步处理机制;
一般而言,父进程在生成子进程之后会有两种情况:一是父进程完成自己的任务,二是父进程不做任务,一直在wait子进程退出。
SIGCHLD信号就是为第一种情况准备的,它让父进程去做别的任务,而只要父进程注册了处理该信号的函数,在子进程退出时就会调用该函数,在函数中wait子进程得到终止状态之后再继续做父进程的事情。
注:
1)凡父进程不调用wait函数族获得子进程终止状态的条件下,子进程在退出时都会变成僵尸进程
2)SIGCHLD信号可以异步通知父进程有子进程退出。
参考:
//=======================以下为自己实现==================
import multiprocessing as ms
import time,os
import signal
#def receive_signal(signum, stack):
# print ('Received:', signum)
#signal.signal(signal.SIGUSR1, receive_signal)
#signal.signal(signal.SIGUSR2, receive_signal)
#def signal_usr1(signum, frame):
# "Callback invoked when a signal is received"
# pid = os.getpid()
# print ('Received USR1 in process %s' % pid)
def signal_process(signum, frame):
pid = os.getpid()
print ('Received process in process %s' % pid)
os.wait()
print ('My PID is:', os.getpid())
def test(name):
count=0;
while True:
if(count == 20):
break
print("in test = {}, count={}".format(name, count))
count += 1
time.sleep(1)
#p1 = ms.Process(target=test, args=('a',)) # process创建子进程的方式
#p1.start()
#p1.join()
pid = os.fork() # fork创建子进程的方式
if pid==0:
print("in child process, {} create child process{}".format(os.getppid(),os.getpid()))
#signal.signal(signal.SIGUSR1, signal_usr1) # 3.子进程注册信号处理函数
test('a')
os._exit(0)
else:
print("in parent process, {} create child process{}".format(os.getpid(),pid))
#signal.signal(signal.SIGCHLD, signal_process) # 2.主进程接收子进程退出信号,回调处理回收
signal.signal(signal.SIGCHLD, signal.SIG_IGN) #1.主进程忽略,子进程自动回收
#os.wait()
#os.kill(os.getpid(), signal.SIGUSR1) # 3.主进程向子进程传递信号,进行通信
while True:print("in main, pid={}".format(os.getpid()))
time.sleep(1)