繁体   English   中英

需要在Windows / Python中快速创建大量新进程

[英]Need to create a large number of new processes very quickly in Windows/Python

为了测试一些安全软件,我需要能够在Windows中创建一个大的(可配置的)新进程(不是线程!),非常快,让它们存在一段(可配置的)时间,然后干净地终止。 这些过程根本不应该做任何事情 - 只存在指定的持续时间。

最终,我希望能够运行如下:

C:\> python process_generate.py --processes=150 --duration=2500

它可以非常快速地创建150个新进程,使它们在2500毫秒内保持活动状态,然后让它们尽快终止。

作为一个起点,我跑了

from multiprocessing import Process
import os

def f():
    pass

if __name__ == '__main__':
    import datetime
    count = 0
    startime = datetime.datetime.now()
    while True:
        p = Process(target=f)
        p.start()
        p.terminate()
        count += 1
        if count % 1000 == 0:
            now = datetime.datetime.now()
            print "Started & stopped d processes in %s seconds" % (count, str(now-starttime))

并且发现我可以在笔记本电脑上连续创建和终止大约70个进程/秒,创建的进程会立即终止。 约70个过程/秒速率持续约一小时的持续时间。

当我将代码更改为

from multiprocessing import Process
import os
import time

def f_sleep():
    time.sleep(1)

if __name__ == '__main__':
    import datetime
    starttime = datetime.datetime.now()

    processes = []
    PROCESS_COUNT = 100
    for i in xrange(PROCESS_COUNT):
        p = Process(target=f_sleep)
        processes.append(p)
        p.start()
    for i in xrange(PROCESS_COUNT):
        processes[i].terminate()
    now = datetime.datetime.now()
    print "Started/stopped %d processes in %s seconds" % (len(processes), str(now-starttime))

并为PROCESS_COUNT尝试了不同的值,我预计它会比它更好地扩展。 我得到了不同的PROCESS_COUNT值的以下结果:

  • 20个过程在0.72秒内完成
  • 30个过程在1.45秒内完成
  • 50个过程在3.68秒内完成
  • 100个过程在14秒内完成
  • 200个过程在43秒内完成
  • 在77秒内完成300个过程
  • 400个过程在111秒内完成

不是我的预期 - 我希望能够以合理线性的方式扩展并行进程计数,直到我遇到瓶颈,但我似乎几乎是直接打击了进程创建的瓶颈。 根据我运行的第一个代码,我肯定希望在遇到进程创建瓶颈之前能够创建接近70个进程/秒的东西。

没有完整的规格,笔记本电脑运行完全修补的Windows XP,具有4Gb RAM,否则是空闲的,是相当新的; 我认为这不会很快成为瓶颈。

我在使用我的代码做了什么明显的错误,或者在12个月大的笔记本电脑上创建的XP / Python并行进程是否真的效率低下?

嗯,Windows进程管理并不能很好地扩展。 进程越多,将新的进程插入调度所需的时间就越长。

现在将其与其他操作系统内核进行比较,例如Linux,其中进程创建实际上是O(1)(常量时间),因为内核2.6.8(当引入了调度程序时)。

请注意,我不打算在这里向你推销Linux。 我建议您在不同的操作系统上试用您的程序,亲眼看看。

在对一系列不同场景进行分析和测试之后,我发现在Windows下生成和终止单个进程要快得多,而不是一次生成N个进程,杀死所有N,然后再次重新启动N.

我的结论是Windows保留了足够的资源,可以很快地启动1个进程,但不足以启动> 1个新的并发进程而没有相当大的延迟。 正如其他人所说,Windows在启动新进程方面进展缓慢,但显然速度会随着系统上已经运行的并发进程数量而逐渐降级 - 开始一个进程非常快,但是当你开始多个进程时你遇到了问题。 无论存在的CPU数量,机器的繁忙程度(通常在我的测试中<5%CPU),Windows是在物理服务器上运行还是在虚拟机上运行,​​有多少RAM可用(我测试的最高可达32Gb),这都适用RAM,~24Gb免费),... - 它似乎只是Windows操作系统的限制。 当我在相同的硬件上安装Linux时,限制消失了(根据Xavi的回应)我们能够非常快速地同时启动许多进程。

我已经在Ubuntu 11.04 Dell Precision和4Gb RAM中测试了您的代码,结果如下:

Started/stopped 100 processes in 0:00:00.051061 seconds
Started/stopped 150 processes in 0:00:00.094802 seconds
Started/stopped 200 processes in 0:00:00.153671 seconds
Started/stopped 300 processes in 0:00:00.351072 seconds
Started/stopped 400 processes in 0:00:00.651631 seconds
Started/stopped 470 processes in 0:00:01.009148 seconds
Started/stopped 1000 processes in 0:00:02.532036 seconds
Started/stopped 10000 processes in 0:00:29.677061 seconds

每次执行时,至少有10%的可变性具有相同数量的进程,希望这是有用的,在一秒钟内,我的计算机用您的代码执行了近500个进程。

如果我没记错,与Linux相反,Windows从未被设计为快速启动许多进程。 这不是设计师认为你会做的事情 - 而在linux上,有像inetd等东西,它是一个足够普遍的操作模型来保证优化 - 所以,流程创建就像地狱一样优化了。

我想说,在Linux中,创建许多Python进程也存在困难。 经过500次运行p.start()后,它变得非常慢。

有时我需要创建数千个可以长时间工作的流程。

在上面的示例中,在一个时刻内没有PROCESS_COUNT个活动进程的数量,因为它们在1秒后开始完成工作。 因此,如果在2秒内创建1000个进程,则超过一半的进程完成直到创建过程结束。

from multiprocessing import Process
def sample():
        sleep(13)
start = time()
for i in range(1500):
    p = Process(target=sample)
    p.daemon = True
    p.start()
 end = time()
 print end - start 

我尝试使用SUSE ENTERPRISE的140核服务器和我的笔记本电脑上的Ubuntu - 动态是相同的(服务器结果):

500 processes start  - 1.36 s
1000 processes start - 9.7 s
1500 processes start - 18.4 s
2000 processes start - 24.3 s
3000 processes start - 43.3 s

因为叉前这个调用。 每个新的子进程都需要更长的时间

def _cleanup():
    # check for processes which have finished
    for p in list(_current_process._children):
        if p._popen.poll() is not None:
            _current_process._children.discard(p)

我记得,如果进程有manager.Value并且稍微重一点 - 它需要10 GB的RAM并且启动时间会更长。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM