3

我在使用 python RQ 运行多线程任务时遇到问题(在 v0.5.6 和 v0.6.0 上测试)。

考虑以下代码,作为我想要实现的简化版本:

东西.py

from threading import Thread

class MyThing(object):
    def say_hello(self):
        while True:
            print "Hello World"

    def hello_task(self):
        t = Thread(target=self.say_hello)
        t.daemon = True # seems like it makes no difference
        t.start()
        t.join()

主文件

from rq import Queue
from redis import Redis
from thing import MyThing

conn = Redis()

q = Queue(connection=conn)

q.enqueue(MyThing().say_hello, timeout=5)

执行时main.py(当 rqworker 在后台运行时),作业在 5 秒内按超时中断。

问题是,当我设置一个包含线程/s 的任务时MyThing().hello_task,线程永远运行,当 5 秒超时结束时没有任何反应。

如何使用 RQ 运行多线程任务,这样超时会杀死任务、它的儿子、孙子和他们的妻子?

4

1 回答 1

2

当你运行t.join()时,hello_task线程阻塞并等待直到say_hello线程返回——因此没有收到来自 rq 的超时信号。您可以允许主线程运行并通过使用Thread.join设定的等待时间来正确接收超时信号,同时等待线程完成运行。像这样:

def hello_task(self):
    t = Thread(target=self.say_hello)
    t.start()
    while t.isAlive():
        t.join(1)  # Block for 1 second

这样,如果您愿意,您还可以捕获超时异常并进行处理:

def hello_task(self):
    t = Thread(target=self.say_hello)
    t.start()
    try:
        while t.isAlive():
            t.join(1)  # Block for 1 second
    except JobTimeoutException:  # From rq.timeouts.JobTimeoutException
        print "Thread killed due to timeout"
        raise
于 2016-08-03T14:52:40.630 回答