将任务放置在子进程或其他线程中执行, 在子进程或其他线程执行超时, 则父进程或主线程程序并退出
fork 进程
- 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"
- Threading.Event
全局定义了一个内置标志 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)
来源: http://www.bubuko.com/infodetail-3112520.html