Python process
2016-04-03 22:15
393 查看
进程通信
subprocess
执行程序,获取返回码或输出信息。call: 返回 ExitCode。
check_call: 如果 ExitCode = 0,抛出 CalledProcessError 异常。
check_output: 返回输出信息。ExitCode = 0 抛出异常。
命令行参数可以用 shlex.split 分解成列表。
>>> from subprocess import * >>> from shlex import split >>> s = check_output(split("ls -l")) >>> print s total 0 drwx------+ 4 yuhen staff 136 1 11 07:40 Desktop drwx------+ 10 yuhen staff 340 1 4 01:53 Documents drwx------+ 4 yuhen staff 136 1 11 08:35 Downloads drwx------@ 56 yuhen staff 1904 1 11 08:28 Library drwx------+ 3 yuhen staff 102 9 22 15:20 Movies drwx------+ 5 yuhen staff 170 1 9 19:37 Music drwx------+ 5 yuhen staff 170 1 3 21:14 Pictures drwxr-xr-x+ 4 yuhen staff 136 9 15 16:21 Public
如果需要获取 ExitCode,又不想看到输出信息。可以将 stdout 重定位到 /dev/null。
>>> null = open(os.devnull, "w") >>> call(split("ls -l"), stdout = null, stderr = null) 0
官方建议用 subprocess 代替 os.system、os.spawn、os.popen、popen2.、commands.这个传统用法。基于以后向 Python 3 迁移的需要,还是放弃所有打上 obsolete 标记的库。
>>> from subprocess import Popen, PIPE >>> Popen('find . -name "*.py" | xargs ls -l', shell=True).wait() -rwxr-xr-x 1 yuhen staff 286 5 29 19:24 ./main.py -rw-r--r-- 1 yuhen staff 76 6 7 17:49 ./test.py
可以用 PIPE 改变输入输出对象。
>>> p = Popen('find . -name "*.py" | xargs ls -l', shell=True, stdout=PIPE) >>> p.pid 71474 >>> print p.stdout.read() -rwxr-xr-x 1 yuhen staff 286 5 29 19:24 ./main.py -rw-r--r-- 1 yuhen staff 76 6 7 17:49 ./test.py >>> p.wait() 0
除使用简便函数外,还可以创建 Popen 对象以获取更细节的控制。subprocess 不能控制终端和 TTY 交互程序,建议使用第三方库 Fabric 或 pexpect。进程信息可以用 psutil 获取。
22.2 signal
信号是软中断,提供了一种异步事件通知机制。Python 默认已经安装了一些信号处理器,比如 SIGPIPE 被忽略,SIGINT 引发 KeyboardInterrupt 异常,捕获 SIGTERM 调用退出函数。常用信号
SIGINT: 用户中断 (ctrl + c)。
SIGTERM: 由 kill() 发送,进程终止。
SIGCHLD: 子进程终止。
SIGHUP: 终端会话终止。
SIGSTP: 进程暂停 (ctrl + z)。
SIGALRM: 告警。
注意: 信号 SIGKILL、SIGSTOP 不能被捕获。
signal
仅能在主线程调用 signal() 注册信号处理器函数,它会移除当前处理动作。可用 getsignal() 获取,在需要时重新注册。有两个特殊的处理器:SIG_IGN 忽略信号,SIG_DFL 默认处理。
试着用 SIGINT 代替 KeyboardInterrupt 异常来处理用户中断。
from signal import * from time import time, sleep def sig_handler(signum, frame): print "exit" exit(0) def main(): signal(SIGINT, sig_handler) while True: sleep(1) print time() if __name__ == "__main__": main()
输出:
$ ./main.py 1357987332.33 1357987333.33 1357987334.33 ^Cexit
中断信号被拦截,我们可以自主决定是否终止进程。在 GDB 里,用 SIGINT 来处理调试中断。也有一些软件用 SIGUSR1、SIGUSR2 作为外部通知事件,比如重启什么的。信号处理会被带入 fork()创建的子进程。
pause
函数 pause() 会使进程休眠,直到进程接收到信号。信号要么被处理,要么终止进程。
def sig_handler(signum, frame): print "sig:", signum def main(): signal(SIGUSR1, sig_handler) while True: print time() pause()
如果收到 SIGUSR1 信号,则进程苏醒后显示时间,然后再次休眠。如是其他信号,进程终止。
alarm
在 n 秒后发送一个 SIGALRM 告警信号。或用 0 秒取消所有尚未到期的告警。
signal(SIGALRM, sig_alarm) # 捕获信号 alarm(2) # 2 秒后发送告警信号。仅一次。
timer
用来设置在 seconds 秒后发出信号,并在此以后每隔 interval 秒重复发出信号。参数 which 决定了发出何种信号。
ITIMER_REAL: SIGALRM
ITIMER_VIRTUAL: SIGVTALRM
ITIMER_PROF: SIGPROF
signal(SIGALRM, sig_alarm) setitimer(ITIMER_REAL, 2, 5) # 2 秒后首次发出信号,随后每隔 5 秒发一次。
将 seconds 设置为 0,将清除定时器。
多进程( multi-process)
[python] view
plain copy
print?
import multiprocessing
def thread_func():
print "thread in"
while True:
pass
if __name__ == "__main__":
t1 = multiprocessing.Process(target = thread_func)
t1.start()
t2 = multiprocessing.Process(target = thread_func)
t2.start()
t1.join()
t2.join()
多线程(multi-thread)
[python] view
plain copy
print?
from threading import Thread
def thread_func():
print "thread in"
while True:
pass
if __name__ == "__main__":
t1 = Thread(target = thread_func)
t1.start()
t2 = Thread(target = thread_func)
t2.start()
t1.join()
t2.join()
相关文章推荐
- Parsing XML in Python&Assignment
- mysql-python安装时EnvironmentError: mysql_config not found
- python shlex
- urlib2下载器网页的三种方法
- (6) Python 语句和语法 –- 条件和条件语句
- Python中创建字典的几种方法
- python版本不一致
- Python序列概述
- [GitPython]使用python管理你的git库
- python语言学习7——数据类型和变量
- 利用NLTK在Python下进行自然语言处理
- Python机器学习包scikit-learn安装步骤,包含了各种可能遇到的错误!!!
- [置顶] python 中 #!/usr/bin/env python 与 #!/usr/bin/python的区别
- python 异常处理
- python3.4.4实现网页爬虫基础之网页下载器三种方法
- Apriori算法简介及实现(python)
- python截取郑州大学贴吧网页
- python入门(一)
- 深刻理解Python中的元类(metaclass)
- python web框架——初识tornado