在python多处理中从bash调用另一个应用程序非常慢

时间:2019-02-25 09:47:13

标签: python multiprocessing concurrent.futures

我正在尝试使用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方法在analyticsApk方法内部称为):

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的分析过程中进程状态的快照:

enter image description here

我通过分析2个apk来测试该应用程序,并且看起来表现得“不错”。相对于在该apk上执行单个分析,我发现qark apk分析的执行时间有所增加。将其归因于多处理,并且发现它并不过分,我认为这还可以...但是100 apk的执行却导致了灾难。

有人可以帮忙看看这里发生了什么吗?为什么分析这么慢?它怎么会弄乱我的Windows分区? RAM内存费用太高,无法分析这么多apk?这是由于我的应用程序中流程使用不当吗? 我该怎么做对呢?

1 个答案:

答案 0 :(得分:0)

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个apk是一个很大的负载。预计需要一段时间。如果对资源的需求过多,竞争条件可能会导致性能比分配的资源更少。您应该调整处理程序,甚至调整memory usage