python - 在 python 多处理中从 bash 调用另一个应用程序非常慢
问题描述
我正在尝试使用qark分析器来分析一组使用 python 进行多处理的 apk。
尝试分析一组 100 个 apk,我发现我编写的用于自动化分析的应用程序非常慢。最后一次分析我运行了大约 20 个小时,然后我手动关闭了我的电脑,因为它变得无法使用,可能是由于大量的 RAM 使用......分析甚至是有害的,弄乱了我的 Windows 分区并阻止了我查看分区内的数据和 Windows 以启动(我从 ubuntu 运行分析,但进入我的 Windows 分区以获取可用磁盘空间)
在这个过程中执行的类的核心是非常类似于
def scanApk(self):
try:
#Creating a directory for qark build files (decompiled sources etc...)
buildDirectoryPath = os.path.join(os.path.join(self.APKANALYSIS_ROOT_DIRECTORY, "qarkApkBuilds"), "build_" + self.apkInfo["package_name"])
os.mkdir(buildDirectoryPath)
start = timer()
subp = subprocess.Popen(self.binPath + "/qark --report-type json --apk \"" + self.apkPath + "\"", cwd=buildDirectoryPath, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
preexec_fn=os.setsid)
#Setting a timeout of 6 hours for the analysis
out, err = subp.communicate(timeout= 6 * (60 * 60))
self.saveOutAndErr(out, err)
if subp.returncode != 0:
raise subprocess.CalledProcessError(subp.returncode, "qark")
self.printAnalysisLasting(start)
#Moving qark report into qark reports collecting directory
subp = subprocess.Popen("mv \"" + self.defaultReportsPath + "/" + self.apkInfo["package_name"] + ".json\" " + "\"" + self.toolReportsDirectory + "\"", shell=True)
out, err = subp.communicate()
if subp.returncode != 0:
raise subprocess.CalledProcessError(subp.returncode, "qark")
return True
[... subprocess.TimeoutExpired and subprocess.CalledProcessError exceptions handling...]
我像这样使用concurrent.futures的ProcessPoolExecutor在多处理中使用该类(scanApk 方法在 analyzeApk 方法中调用):
with concurrent.futures.ProcessPoolExecutor(max_workers = 10) as executor:
futuresList = []
#Submitting tasks to ProcessPoolExecutor
for apkPath in apksToAnalyzePaths:
...
qarkAnalyzer = QarkAnalyzer(...)
futuresList.append(executor.submit(qarkAnalyzer.analyzeApk))
for future in futuresList:
future.result()
相反,这是在分析 htop 显示的 2 个 apk 期间进程状态的快照:
我通过对 2 个 apk 的分析测试了该应用程序,它的表现似乎“不错”......相对于对该 apk 执行单一分析,我经历了 qark apk 分析的执行时间增加,但我将其归因于多处理,并且看到它不是太多,我认为它可能没问题......但是对于 100 个 apk,执行导致了一场灾难。
有人可以帮忙找出这里发生了什么吗?为什么分析这么慢?它怎么会弄乱我的 Windows 分区?RAM 内存费用对于分析这么多的 apk 来说太重了?这是由于我的应用程序中的进程使用不当造成的吗?我怎样才能正确地做这件事?
解决方案
您的 Windows 分区可能发生的情况是 qark 的输出 JSON 文件被写入磁盘的某个重要区域,破坏了某些数据结构,例如 MFT(如果您使用 NTFS)。
在您的代码中,您生成 10 个工作线程。这些都是内存和处理密集型线程。除非您拥有超过 10 个内核,否则这将消耗您所有的处理能力,触发超线程(如果可用)并使系统变得太慢。
为了从您的系统中获得最大性能,您必须为每个工作核心运行一个线程。为此,请运行:
with concurrent.futures.ProcessPoolExecutor(max_workers = os.cpu_count()) as executor:
futuresList = []
. . .
另一个问题是已知静态分析会导致 qark 出现问题。
最后,请注意 100 个 apk 是一个很大的负载。预计需要一段时间。如果资源请求过多,竞争条件可能会导致性能比分配较少资源时更差。你应该调整你的处理甚至内存使用。
推荐阅读
- android - Material Button 正在关闭我在虚拟设备中的应用程序
- android - Android改造,只检索二级对象数组
- drupal - 布尔类型字段上的 Drupal 9 视图过滤器
- clang-tidy - 如何在 Clang AST 中仅识别用户定义的变量?
- php - 图像末尾的后门代码是如何执行的?
- node.js - 如何从另一个云功能更新一个云功能?
- typescript - 嵌套对象类型的 TypeScript keyof
- docker - GKE Autopilot Ingress 部署后 5-15 分钟返回 502 错误
- types - Python 3 中不同格式的返回类型
- python - 最好使用语法或正则表达式解析表格