新手在这里Python
和sympy
.我有一个简单的问题。
如果我使用多处理启动一个工作线程,并在join
调用中给它一些小的超时,比如 3 秒。如果工作人员本身很忙,可能正在等待完成某些事情,会发生什么?当超时到期并且工作线程本身正在等待sympy
时会发生什么?
我发现,如果工作线程在长时间计算中调用sympy
,则联接挂起等待工作线程,比超时时间长得多。
这是一个 MWE
from multiprocessing import Process, Queue
from sympy import *
x = symbols('x')
def worker(integrand,que):
que.put(integrate(integrand, x))
if __name__ == '__main__':
que = Queue()
result = "still waiting "
#this first call works OK since it is easy integral
#action_process = Process(target=worker,args=(cos(x),que))
#this one hangs inside sympy since hard integral
p = Process(target=worker,args=(1/(x**3+cos(x)),que))
# start the process and wait for max of 3 seconds.
p.start()
p.join(timeout=3)
result=que.get()
print("result from worker is " + str(result))
p.terminate()
问:是否可以强制工作线程在超时时终止?有没有其他选择可以做到这一点?我在上面做错了什么吗?
如果无法在连接时强制超时,那么如果工作线程无法加入,那么 n 秒后的 join(( 是什么意思?
我尝试上述操作的唯一原因是找到一种方法 在sympy
中长时间计算超时,因为我在窗口和计时器和警报在窗口上不起作用,所以我想尝试超时的多处理,但它似乎没有做我想要的,因此这对我想要的没有任何用处。
PS. 如果您运行上述操作,工人将在sympy
内长时间悬挂,可能是 10 分钟或更长时间,并且可能不得不手动杀死它。
以上是在窗户上。但是我也尝试过Linux,它也挂起了。
Anacode 4.3.1, Python 3.6
更新
感谢回答中的提示,下面似乎现在有效
from multiprocessing import Process, Queue
from sympy import *
x = symbols('x')
def worker(integrand,que):
que.put(integrate(integrand, x))
if __name__ == '__main__':
que = Queue()
result = "timed out "
#this one hangs inside sympy since hard integral
p = Process(target=worker,args=(1/(x**3+cos(x)),que))
# start the process and wait for max of 3 seconds.
p.start()
p.join(timeout=3)
try:
result=que.get(block=False)
except:
print("timed out on que.get()")
pass
print("result from worker is " + str(result))
p.terminate()
我仍然需要对其进行更多测试,以确保 worker process(( 确实被终止杀死,因为我不想有僵尸工人在身边。
你的代码永远不会"及时"到达print
的原因是因为它没有超越result=que.get()
。您指定了p.join
超时,使调用进程在指定的超时后恢复。但是,que.get
也会阻塞,因此会等到项目被放入队列中。您也可以在此处指定超时:que.get(timeout=...)
或干脆关闭阻止:que.get(block=False)
。在任何情况下,如果队列中没有可用项,则会引发queue.Empty
异常。
但是,该文档包含有关终止包含对队列的(共享(引用的进程的几个警告。编程指南似乎包含针对这种情况的解决方案,并且还警告了可能的死锁(请参阅"加入使用队列的进程"(。