Python 多处理的语义是什么.使用超时加入.为什么挂



新手在这里Pythonsympy.我有一个简单的问题。

如果我使用多处理启动一个工作线程,并在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异常。

但是,该文档包含有关终止包含对队列的(共享(引用的进程的几个警告。编程指南似乎包含针对这种情况的解决方案,并且还警告了可能的死锁(请参阅"加入使用队列的进程"(。

最新更新