python练习笔记——处理僵尸进程

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信号可以异步通知父进程有子进程退出。

 

参考:

signal(SIGCLD,SIG_IGN)

linux下的僵尸进程处理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)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值