在 python 多处理中从 bash 调用另一个应用程序非常慢
calling another application from bash in python multiprocessing is very slow
我正在尝试使用 qark 分析器在使用 python 的多处理中分析一组 apk。
在尝试分析一组 100 个 apk 时,我发现我编写的自动分析应用程序非常慢。上次分析我运行执行了大约20个小时,然后我手动关闭了我的电脑,因为它变得无法使用,可能是由于RAM使用率过高......分析甚至有害,弄乱了我的 Windows 分区 并阻止我看到分区内的数据和 Windows 无法启动(我 运行 来自 ubuntu 的分析,但是进入我的 Windows 分区以获得空闲磁盘 space)
进程中执行的class核心与
非常相似
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...]
我在多处理中使用 class 使用 concurrent.futures' ProcessPoolExecutor 像这样(在 analyzeApk 方法中调用 scanApk 方法):
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 的分析测试了应用程序,它似乎表现得很好 "nice"...我发现 qark apk 分析的执行时间相对于执行单一分析有所增加apk,但我把它归因于多处理,看到它并不过分,我认为它可能没问题......但是对于100个apks,执行导致了灾难。
有人可以帮忙看看这里发生了什么吗?为什么分析这么慢?它怎么会弄乱我的 Windows 分区? RAM 内存占用太大,无法分析如此多的 apk?这是由于我的应用程序中流程使用不当造成的?
我怎样才能正确地做这件事?
您的 Windows 分区可能发生的事情是 qark 的输出 JSON 文件被写入磁盘中的某个重要区域,破坏了一些数据结构,例如 MFT(如果您使用NTFS).
在您的代码中,您产生了 10 个工作线程。这些都是内存和处理密集型线程。除非你有超过 10 个内核,否则这将消耗你所有的处理能力,触发超线程(如果可用)并使系统变得太慢。
要获得系统的最大性能,您必须 运行 每个工作核心一个线程。为此,运行:
with concurrent.futures.ProcessPoolExecutor(max_workers = os.cpu_count()) as executor:
futuresList = []
. . .
另一个问题是 static analysis is known to cause problems with qark.
最后,请注意 100 个 apks 是一个很大的负载。预计需要一段时间。如果资源被过度请求,竞争条件会导致性能比分配较少资源时更差。你应该调整你的处理甚至 .
我正在尝试使用 qark 分析器在使用 python 的多处理中分析一组 apk。
在尝试分析一组 100 个 apk 时,我发现我编写的自动分析应用程序非常慢。上次分析我运行执行了大约20个小时,然后我手动关闭了我的电脑,因为它变得无法使用,可能是由于RAM使用率过高......分析甚至有害,弄乱了我的 Windows 分区 并阻止我看到分区内的数据和 Windows 无法启动(我 运行 来自 ubuntu 的分析,但是进入我的 Windows 分区以获得空闲磁盘 space)
进程中执行的class核心与
非常相似 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...]
我在多处理中使用 class 使用 concurrent.futures' ProcessPoolExecutor 像这样(在 analyzeApk 方法中调用 scanApk 方法):
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 的分析测试了应用程序,它似乎表现得很好 "nice"...我发现 qark apk 分析的执行时间相对于执行单一分析有所增加apk,但我把它归因于多处理,看到它并不过分,我认为它可能没问题......但是对于100个apks,执行导致了灾难。
有人可以帮忙看看这里发生了什么吗?为什么分析这么慢?它怎么会弄乱我的 Windows 分区? RAM 内存占用太大,无法分析如此多的 apk?这是由于我的应用程序中流程使用不当造成的? 我怎样才能正确地做这件事?
您的 Windows 分区可能发生的事情是 qark 的输出 JSON 文件被写入磁盘中的某个重要区域,破坏了一些数据结构,例如 MFT(如果您使用NTFS).
在您的代码中,您产生了 10 个工作线程。这些都是内存和处理密集型线程。除非你有超过 10 个内核,否则这将消耗你所有的处理能力,触发超线程(如果可用)并使系统变得太慢。
要获得系统的最大性能,您必须 运行 每个工作核心一个线程。为此,运行:
with concurrent.futures.ProcessPoolExecutor(max_workers = os.cpu_count()) as executor:
futuresList = []
. . .
另一个问题是 static analysis is known to cause problems with qark.
最后,请注意 100 个 apks 是一个很大的负载。预计需要一段时间。如果资源被过度请求,竞争条件会导致性能比分配较少资源时更差。你应该调整你的处理甚至