`

Python2如何让子进程超时

阅读更多

       总结:

        python3 subprocess  wait communicate 都有timeout 

       python2 没有,且一些属性都不一样

      有一天我碰到一个需求,我需要和子进程交互,并且需要让它在一定时间内超时。不幸的,Python2没有让communicate方法超时的办法,所以communicate会一直运行到返回或者子进程自己关闭它。我在StackOverflow上找到很多中办法来解决这个问题,但是我想我最喜欢的办法是使用Python的Threading模块的Timer类:

import subprocess
from threading import Timer

kill = lambda process: process.kill()
cmd = ['ping', 'www.google.com']
ping = subprocess.Popen(
    cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
my_timer = Timer(5, kill, [ping])
try:
    my_timer.start()
    stdout, stderr = ping.communicate()
finally:
    my_timer.cancel()

这个例子和我的实际需求并不完全一致,但是已经很像了。首先,这里我们有一个会一直运行下去的进程,并且我们需要和这个进程交互。在Linux上,如果你调用ping,那么它就会一直运行下去。这就是一个很好的例子。这里我写了一个lambda函数killing,这个函数会调用进程的kill方法。当我启动ping命令,并把它放在计时器里,这个计时器五秒超时,然后启动定时器。当这个进程运行时,我们搜集进程的标准输出和错误输出,直到进程死掉。最后,我们停止计时器清场。

 

Python3.5增加了一个能够接受一个timeout参数的run函数。根据文档,这个timeout参数会被传递给子进程的communicate方法,并且进程超时时会抛出一个TimeoutExpired异常。让我们来试一试:

>>> import subprocess
>>> cmd = ['ping', 'www.google.com']
>>> subprocess.run(cmd, timeout=5)
PING www.google.com (216.58.216.196) 56(84) bytes of data.
64 bytes from ord31s21-in-f4.1e100.net (216.58.216.196): icmp_seq=1 ttl=55 time=16.3 ms
64 bytes from ord31s21-in-f4.1e100.net (216.58.216.196): icmp_seq=2 ttl=55 time=19.4 ms
64 bytes from ord31s21-in-f4.1e100.net (216.58.216.196): icmp_seq=3 ttl=55 time=20.0 ms
64 bytes from ord31s21-in-f4.1e100.net (216.58.216.196): icmp_seq=4 ttl=55 time=19.4 ms
64 bytes from ord31s21-in-f4.1e100.net (216.58.216.196): icmp_seq=5 ttl=55 time=17.0 ms
Traceback (most recent call last):
  Python Shell, prompt 3, line 1
  File "/usr/local/lib/python3.5/subprocess.py", line 711, in run
    stderr=stderr)
subprocess.TimeoutExpired: Command '['ping', 'www.google.com']' timed out after 5 seconds

显然确实就像文档中所说。这真的很有用,通常我们需要捕获这个异常

>>> try:
...     subprocess.run(cmd, timeout=5)
... except subprocess.TimeoutExpired:
...     print('process ran too long')
... 
PING www.google.com (216.58.216.196) 56(84) bytes of data.
64 bytes from ord31s21-in-f196.1e100.net (216.58.216.196): icmp_seq=1 ttl=55 time=18.3 ms
64 bytes from ord31s21-in-f196.1e100.net (216.58.216.196): icmp_seq=2 ttl=55 time=21.1 ms
64 bytes from ord31s21-in-f196.1e100.net (216.58.216.196): icmp_seq=3 ttl=55 time=22.7 ms
64 bytes from ord31s21-in-f196.1e100.net (216.58.216.196): icmp_seq=4 ttl=55 time=20.3 ms
64 bytes from ord31s21-in-f196.1e100.net (216.58.216.196): icmp_seq=5 ttl=55 time=16.8 ms
process ran too long

现在我们捕获到了这个异常,我们可以做些其他的事情,比如保存异常信息。有趣的是,事实上,在Python3.3 subprocess就有了timeout参数。你可以在subprocess.call, check_output, 和 check_call中使用timeout参数,在Popen.wait()中也有timeout参数。

分享到:
评论

相关推荐

    Python进程Process模块-Python零基础入门教程.pdf

    - `join([timeout])`: 等待子进程结束,可选参数`timeout`设定超时时间。 - `daemon`: 设置进程为守护进程,父进程退出时,守护进程也会随之退出。设置为`True`后,该进程不能创建子进程。 - `name`: 进程的名称。 -...

    PyPI 官网下载 | python-subprocess-utils-0.0.1.tar.gz

    Python Subprocess Utils 是一个Python开发的后端工具库,它扩展了Python标准库中的`subprocess`模块,提供了更方便的方式来管理和控制子进程。在Python编程中,`subprocess`模块是用于创建新的进程、连接到它们的...

    python多进程控制学习小结

    print(f'这是子进程[{num}]...', flush=True) if __name__ == '__main__': for i in range(5): p = multiprocessing.Process(target=worker, args=(i,)) print(f'启动进程数:{i}', flush=True) p.start() p....

    Python 2.x如何设置命令执行的超时时间实例

    2. **子进程启动**:使用`subprocess.Popen`启动一个子进程并重定向其标准输出和标准错误流。 3. **定时器设置**:创建一个`Timer`对象,设置超时时间为`timeout`秒。当超时发生时,会调用一个lambda表达式,该...

    Python库 | nwsubprocess-0.1.6-py3-none-any.whl

    2. **错误处理**:库可能提供更好的错误处理机制,比如捕获子进程的异常输出,或者当子进程崩溃时自动恢复。 3. **信号处理**:允许发送信号给子进程,如SIGINT(模拟用户中断)或SIGTERM(优雅地结束进程)。 4. ...

    python调用tcpdump抓包过滤的方法

    在Python中调用tcpdump,主要是通过`subprocess`模块来创建子进程,执行tcpdump命令,并与其他进程通信。以下是一个简单的Python脚本,它创建了两个进程:一个是tcpdump进程,另一个是grep进程,用于过滤捕获的...

    详解python中自定义超时异常的几种方法

    在Python编程中,处理超时异常是网络编程和多线程应用中常见的需求。超时异常处理可以提高程序的健壮性,防止因为外部调用或网络请求耗时过长而导致整个程序挂起。本文将介绍如何在Python中自定义超时异常的几种方法...

    Python:pexpect模块下载

    这个例子展示了pexpect的基本用法,实际上它还支持更复杂的模式匹配(如正则表达式)、子进程管理、超时处理等功能。通过深入学习和实践,你可以充分利用pexpect模块来简化那些需要手动交互的自动化任务。

    Python使用multiprocessing创建进程的方法

    在这个例子中,我们创建了一个名为`chain`的递归函数,它会创建一个新的子进程,并递归调用自身直到`howmany`减少到0为止。这样就创建了一个父子关系的进程链。 ##### 示例3:创建进程树 ```python import os from...

    python期货量化书推荐-Python期货量化交易基础教程(12).pdf

    `join(timeout=None)`是阻塞主线程,等待子线程执行完毕的方法,可以设定超时时间。 示例代码中展示了如何创建和管理线程。通过`Thread`类实例化多个线程,每个线程都有不同的参数和目标函数。`start()`方法启动...

    python 进程 进程池 进程间通信实现解析

    创建MyNewProcess类的实例后,调用start方法可以启动一个子进程,该子进程将执行run方法中定义的任务。 当需要处理大量并发任务时,手动创建和管理多个进程会变得复杂。这时,进程池(Pool)可以派上用场。进程池...

    Python实现快速多线程ping的方法

    `run`方法是线程真正执行的地方,它调用了ping命令,并使用`pexpect`库的`spawn`函数来启动子进程。`expect`方法则等待子进程的输出,根据输出判断是否成功接收到响应。 `expect`方法在这里设置了两个匹配模式:...

    Python multiprocessing多进程原理与应用示例

    这里设置为`False`意味着即使主进程结束,子进程也会继续运行,直到它们的任务完成。 - **`p1.start()`** 和 **`p2.start()`**:分别启动两个子进程。 - **`p1.terminate()`**:立即终止进程`p1`,不论其是否完成了...

    Python-pexpect在一个伪终端中控制交互程序就像GNUexpect一样

    2. **超时处理**:可以设置等待某个预期模式出现的超时时间,防止程序无限期等待。 3. **非阻塞模式**:使用`expect_list`方法,可以在多个预期模式之间进行非阻塞轮询。 4. **异常处理**:当子进程异常结束时,...

    基于Python的程序评分软件的设计与实现.pdf

    - 采用subprocess模块来创建子进程,执行外部程序,并获取程序的执行结果和时间。 - openpyxl库用于将评分结果写入Excel电子表格。 6. 软件的工作流程: - 配置文件准备:需要一个配置文件programJudge.js,用于...

    Python库 | types_filelock-0.1.3-py2.py3-none-any.whl

    `filelock`库为Python提供了这一功能,支持Unix、Windows和Python的子进程。 2. **平台兼容性**:`filelock`库设计时考虑了跨平台的兼容性,可以在Python 2和3上运行,这由包名称中的`py2.py3`表示。`none-any`表示...

    Python技法:实用运维脚本编写(进程-文件-目录操作).doc

    当需要处理异常情况,比如子进程长时间未结束,我们可以设置超时机制,并捕获 `subprocess.TimeoutExpired` 异常: ```python try: res = subprocess.run(["Python-Lang/while.out"], capture_output=True, time...

    python cs网络编程

    套接字是操作系统提供的接口,用于进程间的网络通信。在Python中,我们可以使用`socket`模块来创建和操作套接字。TCP(传输控制协议)是一种面向连接、可靠的传输协议,它保证了数据的有序和无损传输。 以下是实现...

    机电控制python

    2. **电机控制协议**:电机自带的电子工具箱通常有特定的通信协议,如PWM(脉宽调制)、CAN总线或Modbus等。你需要了解并实现这些协议的Python版本,以便发送指令给电机。例如,如果使用的是PWM,可以通过控制脉冲...

    EasyProcess:易于使用的python子流程界面

    EasyProcess是一个易于使用的python子进程接口。 链接: 主页: : PYPI: ://pypi.python.org/pypi/EasyProcess 特征: 模块顶部的层易于启动,停止程序易于获得标准输出/错误,程序的返回代码命令可以是列表(首选...

Global site tag (gtag.js) - Google Analytics