python - python线程中超时信号的替代方法

标签 python multithreading python-3.x timeout signals

我有一个应用程序,它依赖于一些阻塞操作的超时信号。

例如:

def wait_timeout(signum, frame):
    raise Exception("timeout")

signal.signal(signal.SIGALRM, wait_timeout)
signal.setitimer(signal.ITIMER_REAL, 5)

try:
    while true:
        print("zzz")
        sleep(1)
except Exception as e:
    # timeout
    print("Time's up")

现在我已经使用相同的方法实现了多线程,但是对于所有线程我都得到了ValueError: signal only works in main thread

我假设信号超时的方法不适用于线程。

不幸的是我不能使用这样的东西:

timeout = 5
start = time.time()

while true:
    print("zzz")
    sleep(1)
    if time.time() <= start+timeout:
        print("Time's up)
        break

由于 while 循环中的操作可能会阻塞并可能永远持续下去,因此循环可能永远不会到达 if 子句。

问:如何在线程中实现超时,就像我以前对信号所做的那样?

编辑:我遇到了 this blog post ,显示了与 python 中的 JavaScript 中的 setTimeout() 类似的解决方案。我认为这可能是一个可能的解决方案,但我真的不确定如何使用它。

edit2:我按如下方式在主线程中启动线程:

p = Popen(["tool", "--param", arg], stdin=PIPE, stdout=PIPE, stderr=STDOUT)
t = Thread(target=process_thread, daemon=True, args=(p,arg1,arg2))
t.start()

process_thread 函数通过执行以下操作处理 tool 的标准输出:

for line in p.stdout:
    # process line of the processes stdout

这个过程可能需要很长时间,例如一旦 tool 没有产生任何输出。我只需要 tool 的输出,比方说 5 秒,因此需要在特定超时后中断 for 循环。

这就是我使用信号的原因,但显然它们在线程中不起作用。

edit3: 我已经创建了一个更详尽和准确的示例来说明我打算如何在线程中使用信号。 See the gist here

最佳答案

您正在寻找的是一个看门狗

def watchdog(queue):
    while True:
        watch = queue.get()
        time.sleep(watch.seconds)

        try:
            watch = queue.get_nowait()
            # No except, got queue message, 
            #   do noting wait for next watch

        except queue.Empty:
            os.kill(watch.pid, signal.SIGKILL)

def workload_thread(queue):
    pid = os.getpid()
    queue.put({'pid':pid, 'seconds':5})

    # do your work
    # Test Watchdog
    # time.sleep(6)

    queue.put({'pid':pid, 'done':True})

注意:代码未经测试,可能存在语法错误!

关于python - python线程中超时信号的替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42647772/

相关文章:

Python将对象属性写入文件

python - 求解非线性方程组和线性不等式的快速方法?

python - 如何从 gridsearchcv 绘制决策树?

python - 在 Python 中将两个变量绑定(bind)在一起

python - 如何将 2d 列表转换为 2d native python 数组而不是 numpy 数组?

python - 如何持久化 patsy DesignInfo?

java - Java 中的同步多线程(Apache HTTPClient)

c++ - 在对其进行线程操作后保存 GDI+ 位图

java - 用户空间线程和内核空间线程的示例

python - 用于控制 Python 调试消息日志记录的首选方法?