-1

我编写了一个小的 python 函数,它运行 adb shell monkey -p -v 命令以及使用 subprocess.popen 的 adb logcat 命令。对于大于 100 的值,该程序会崩溃,我不知道为什么。

这是monkey_runner.py

import os, subprocess
def run_monkey_process(package, num_commands):
        monkeycmd = "adb shell monkey -p " + package + " -v " + num_commands
        monkeyprocess = subprocess.Popen(monkeycmd, stdout=subprocess.PIPE)
        logcatcmd = "adb logcat"
        logcatprocess = subprocess.Popen(logcatcmd, stdout=subprocess.PIPE)
        monkeystring = monkeyprocess.communicate(input=None)[0]
        logcatstring = logcatprocess.communicate(input=None)[0]
        monkeyreturncode = monkeyprocess.poll()
        logcatreturncode = logcatprocess.poll()


        if(monkeyreturncode >=0):
                monkeyprocess.kill()
                logcatprocess.kill()

                return monkeystring, logcatstring

        else:
                print 'command failure'
                return 'you', 'fail'

我也可以把我的 gui 代码放在这里,但这没什么特别的。

这是堆栈跟踪

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1470, in __call__
    return self.func(*args)
  File "C:\Users\brandon.dalesandro\Desktop\Zonar\mankey\monkey_runner_gui.py", line 25, in goCallBack
    returned = run_monkey_process(package, num)
  File "C:\Users\brandon.dalesandro\Desktop\Zonar\mankey\monkey_runner.py", line 8, in run_monkey_process
    logcatstring = logcatprocess.communicate(input=None)[0]
  File "C:\Python27\lib\subprocess.py", line 798, in communicate
    stdout = _eintr_retry_call(self.stdout.read)
  File "C:\Python27\lib\subprocess.py", line 478, in _eintr_retry_call
    return func(*args)
KeyboardInterrupt
4

1 回答 1

0

可能是您的问题,但如果没有更多信息就很难判断……</p>

您已经为子流程提供了一个管道,但直到它完成后您才读取它。文档中的警告解释了为什么这是不好的:

这将在使用stdout=PIPE和/或时发生死锁,stderr=PIPE并且子进程会向管道生成足够的输出,从而阻塞等待 OS 管道缓冲区接受更多数据。用来communicate()避免这种情况。

它适用于少量命令(当没有足够的数据来填充管道缓冲区时),但对于较大的数字则挂起,这是完全合理的。

循环poll而不是调用wait没有任何帮助。它所做的只是无缘无故地烧掉 100% CPU。您仍然没有从管道中读取。

在过程完成后调用communicate也无济于事。如果管道已填满,子进程将永远被阻塞,永远poll不会返回值,你甚至永远都不会到达communicate.

既然communicate已经做了它自己的wait,它真的是你所需要的:

monkeyprocess = subprocess.Popen(monkeycmd, stdout=subprocess.PIPE, bufsize=1)
monkeystring = monkeyprocess.communicate(input=None)[0]
returncode = monkeyprocess.returncode
于 2013-08-23T00:42:09.273 回答