【发布时间】:2013-11-26 09:04:50
【问题描述】:
我在这 2 个问题中使用了代码
how to get the return value from a thread in python
得到了这个
import subprocess, threading, os
class ThreadWithReturnValue(threading.Thread):
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}, Verbose=None):
threading.Thread.__init__(self, group, target, name, args, kwargs, Verbose)
self._return = None
def run(self):
if self._Thread__target is not None:
self._return = self._Thread__target(*self._Thread__args, **self._Thread__kwargs)
def join(self, timeout = None):
threading.Thread.join(self, timeout)
return self._return
class SubprocessWrapper(object):
def __init__(self, cmd, timeout):
self.cmd = cmd
self.process = None
self.timeout = timeout
def run(self):
def target(cmd):
self.process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr = subprocess.PIPE)
returnValue = self.process.communicate()
return [returnValue[0], returnValue[1], self.process.returncode]
thread = ThreadWithReturnValue(target=target, args=[self.cmd])
thread.start()
returnValue = thread.join(self.timeout)
if thread.is_alive():
print 'cmd = ',self.cmd
self.process.kill()
returnValue = thread.join()
print 'rc = ', returnValue[2]
output = returnValue[0]
error = returnValue[1]
rc = returnValue[2]
return (output, rc)
os.system('date +%T.%N')
s1 = SubprocessWrapper("echo 'Process started'; sleep 2; echo 'Process finished'", timeout = 3)
s1.run()
os.system('date +%T.%N')
s2 = SubprocessWrapper("echo 'Process started'; sleep 2; echo 'Process finished'", timeout = 1)
s2.run()
os.system('date +%T.%N')
问题是输出是
11:20:34.963947950
11:20:36.986685289
cmd = echo 'Process started'; sleep 2; echo 'Process finished'
rc = -9
11:20:38.995597397
因此您可以看到应该在一秒钟后终止的进程实际上花费了 2 秒钟。发生这种情况是因为join() 但在问题subprocess with timeout 中这很好用。这意味着当我集成两个代码时,我导致了这个问题,我的问题是如何解决它?我在想我可能需要以不同的方式调用 threading.Thread.__init__ 方法,但我不明白如何。
【问题讨论】:
-
时间是一件很棘手的事情。对于计算机来说,时间是以晶体的振动来衡量的。对您来说,它以秒为单位,这是基于钟摆的摆动。当您告诉计算机休眠 2 秒时,它会尝试在用户时间休眠,但它必须在计算机时间休眠,因为它不知道用户时间是什么。有时,当这种情况发生时,您会得到微小的差异,因此在处理如此小的时间量时,您无法确定是否存在真正的问题。尝试 100 秒,看看会发生什么。有一种方法可以让时间变得更好,但你必须要求一个新的。
-
@InbarRose:一秒钟是计算机术语的年龄(数十亿次操作)
-
是的,但是当请求让用户知道已经过了多少用户秒的设备时,它有一个非常严格的映射,超过1秒的单个操作算作2秒。在处理如此小的数字时,时间增加了 100%。如果你想运行一个 100 秒的东西,它运行了 101 秒,它只增加了 1% 的时间(尽管它并没有真正增加,只是看起来是这样)
-
@InbarRose,我也使用了更长的时间,没关系,超时到期后
join等到subprocess完成,而在最初的问题中,这是'案例
标签: python multithreading timeout subprocess