import os
import time
import signal
# 信号数和stack框架
def chldhandler(signum, stackframe):
""" signal handler.Runs on the parent and is called whenever
a child terminates."""
while True:
try:
# -1 等待所有子进程
# os.WNOHANG(wait no hang)。如果没有子进程立即返回,如果子进程等待,返回进程pid的tuple
# 退出信息
result = os.waitpid(-1, os.WNOHANG)
except:
break
print "reaped child process %s" %result[0]
# 第一个参数信号,第二个处理信号函数
signal.signal(signal.SIGCHLD, chldhandler)
pid = os.fork()
if pid:
print "hello from the parent.the child pid is :%d" % pid
print "sleeping 10 seconds"
time.sleep(10)
print "sleep done"
else:
print "child sleep 5 seconds"
time.sleep(5)
fork一个子进程,当子进程早于父进程退出时,需要对子进程进行处理,否则子进程会变成zombie进程如下图,直到父进程执行完被清理之后,该子进程变为init的子进程,从而被清理。使用signal.signal(signal.SIGCHILD, chldhander),当子进程退出时,对子进程进行清理。

设计一个在子进程中执行某逻辑,子进程超时120秒,如果子进程在120秒内完成,则子进程清理后,父进程退出。否则,如果120秒没有完成,则使用kill,强制终止子进程,父进程退出。
# coding:utf-8
import os
import time
import signal
flag = False
# 信号数和stack框架
def chldhandler(signum, stackframe):
""" signal handler.Runs on the parent and is called whenever
a child terminates."""
while True:
try:
# -1 等待所有子进程
# os.WNOHANG(wait no hang)。如果没有子进程立即返回,如果子进程等待,返回进程pid的tuple
# 退出信息
result = os.waitpid(-1, os.WNOHANG)
global flag
flag = True
except:
break
print "reaped child process %s" %result[0]
# 第一个参数信号,第二个处理信号函数
signal.signal(signal.SIGCHLD, chldhandler)
pid = os.fork()
if pid:
print "hello from the parent.the child pid is :%d" % pid
print "sleeping 120 seconds"
for i in range(12):
time.sleep(10)
if flag:
break
if not flag:
os.kill(pid, signal.SIGKILL)
print "sleep done", pid
else:
print "child sleep 1 seconds"
time.sleep(122)
print "child sleep end"
全局定义了一个内置标志Flag,如果Flag值为 False,那么当程序执行 event.wait方法时就会阻塞,如果Flag值为True,那么event.wait 方法时便不再阻塞。
-
set() 将标志设为True,并通知所有处于等待阻塞状态的线程恢复运行状态
-
将标志设为False
-
isSet(): 获取内置标志状态,返回True或False
import threading
import time
event = threading.Event()
def do_something(name):
print("%s is read for do something" %name)
event.wait()
print("%s is doing" %name)
thread1 = threading.Thread(target=do_something,args=('caesar',))
thread2 = threading.Thread(target=do_something,args=('ciro',))
threads = []
threads.append(thread1)
threads.append(thread2)
for thread in threads:
thread.start()
print("let's do together!")
if not event.isSet():
event.set()
同理,使用主线程对其他线程监控,若其他线程执行do_something超时,则退出,若其他线程执行完成,主线程退出
import threading
import time
import sys
event = threading.Event()
def do_something(name):
print("%s is read for do something" %name)
print("%s is doing" %name)
event.set()
thread1 = threading.Thread(target=do_something,args=('caesar',))
thread1.start()
for i in range(12):
if not event.isSet():
time.sleep(10)
if not event.isSet():
sys.exit(1)
else:
sys.exit(0)

浙公网安备 33010602011771号