python subprocess32 with timeout,overflowerror

时间:2017-01-09 19:42:13

标签: python python-2.7 subprocess

这是我的日志

File "/opt/ibm/db2-governor/helpers/utils.py", line 10, in run_cmd
output = proc.communicate(timeout = timeout)[0]
  File "/opt/ibm/dynamite/python/lib/python2.7/site-packages/subprocess32.py", line 927, in communicate
    stdout, stderr = self._communicate(input, endtime, timeout)
  File "/opt/ibm/dynamite/python/lib/python2.7/site-packages/subprocess32.py", line 1713, in _communicate
    orig_timeout)
  File "/opt/ibm/dynamite/python/lib/python2.7/site-packages/subprocess32.py", line 1786, in _communicate_with_poll
    ready = poller.poll(self._remaining_time(endtime))
OverflowError: Python int too large to convert to C lon

所以触发它的代码是

output = proc.communicate(timeout = timeout)[0]

超时设置为20,这种情况间歇性地发生(几乎从不发生),即使用python 2.7.11和subprocess32库,这是一个python错误吗?

好的,我检查了subprocess32.py,这行就像这样

endtime = time.time() + timeout

ready = poller.poll(self._remaining_time(endtime))

所以基本上时间戳太大而无法转换成c int,有什么办法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

听起来像个错误。

如果你有兴趣,这是一个变通方案提议:而不是communicate,从一个线程中的进程stdout读取并检查进程是否已经结束,无需再阅读或返回代码产量poll

由于您控制循环,您可以在主线程中等待1秒钟并暂停倒计时(不准确,因为sleep可以漂移,但这样就足够了,而且简单)。当达到0时也杀死进程。

import threading

output = ""

def subp(p):
    global output

    while True:
        # read blocks but since we're in a thread it doesn't matter
        data = proc.stdout.read()
        if not data or proc.poll() != None:
            break
        output += data

# here create the process    
proc = subprocess...

# create a thread, pass the process handle
t = threading.Thread(target=subp,args=(proc,))

while True:
    if proc.poll() != None:
      # exit: OK
      break
    timeout -= 1
    if timeout < 0:
        # took too long: kill
        proc.terminate()
        break
    time.sleep(1)

t.join()