新手在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
中找到一种超长计算超时的方法,因为我在Windows和定时器上并且警报在Windows上不起作用,所以我想尝试使用超时进行多处理,但它似乎没有做我想要的,因此这对我想要的东西没有任何用处。
PS。如果您运行上述操作,工作人员将在sympy
内长时间停留,可能需要10分钟或更长时间,并且可能必须手动将其杀死。
以上是在Windows上。但是我也试过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()
我仍然需要对它进行更多测试,以确保工作进程()确实被终止杀死,因为我不想让僵尸工作者在身边。
答案 0 :(得分:1)
您的代码永远不会及时到达print
“的原因是因为它没有超出result=que.get()
。您为p.join
指定了超时,这使得调用进程在指定的超时后恢复。但是que.get
也是阻塞的,因此等待一个项目进入队列。您也可以在此处指定超时:que.get(timeout=...)
或只是关闭屏蔽:que.get(block=False)
。在任何情况下,如果队列中没有可用的项目,它将引发queue.Empty
例外。
但是,文档包含several warnings有关终止保存(队列)共享引用的进程的信息。 Programming Guidelines似乎包含该案例的解决方案,并警告可能存在死锁(请参阅“加入使用队列的进程”)。