为了测试某些安全软件,我需要能够创建新的进程(不是线程!)在Windows,很快大(配置)号,让他们存在的时间(可配置)周期,然后终止干净。 该过程不应该不惜一切做任何事情 - 只是存在指定的持续时间。
最后,我希望能够像运行的东西:
C:\> python process_generate.py --processes=150 --duration=2500
这将创造150个新的过程非常快,让他们都活着在2500ms为,然后让他们全部终止尽快。
作为一个起点,我跑
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秒内完成
- 300个处理77秒内完成
- 400个处理111秒内完成
这不是我所期待的-我希望能够扩展了并行处理数在一个合理的线性方式,直到我打了一个瓶颈,但我似乎被打的过程创造瓶颈几乎通俗易懂。 我肯定希望能够创造一些接近70个处理/秒命中一个进程创建瓶颈的基础上,我遇到的第一个代码之前。
无需进入全面规范,在笔记本电脑上运行完全修补Windows XP中,拥有4GB内存,处于空闲状态,是合理的新的; 我不认为它会被这个迅速创下了瓶颈。
很显然我在做什么错在这里我的代码,或者是XP / Python的并行进程创建真正的12个月大的笔记本电脑,效率低下?
那么,Windows进程管理并没有真正很好地扩展。 越多的过程也有,时间越长,以插入一个新的进入调度。
现在比较这与其他操作系统内核,例如:Linux的进程创建实际上是O(1)(恒定时间),因为内核2.6.8(当被引入这个能力的调度)。
请注意,我并不想在这里向你推销Linux操作系统。 我只是建议你尝试一下你的程序在不同的操作系统来看一看吧。
分析和测试一堆不同的场景之后,我发现它只是远远快是产生和Windows下杀单的过程,而不是一次生成N个过程,全部遇难N,然后再重新启动ñ。
我的结论是,Windows将保留足够的可用资源能够在一个时间相当迅速启动1点的过程,但没有足够的没有相当大的延迟开始> 1个新的并发进程。 正如其他人表示,Windows是缓慢的,在开始新工艺,但显然速度降低半几何与系统上已运行的并发进程数 - 开始一个单一的过程是相当快的,但是当你踢了多个进程你打的问题。 不管存在的CPU数量,机器有多忙(通常<在我的测试中5%的CPU)的Windows是否是物理服务器还是虚拟的,多的RAM是如何提供上运行这适用(我与高达32GB测试RAM,拥有24GB〜免费),... - 它只是似乎是Windows操作系统的限制。 当我在同一硬件上安装了Linux,限制就走了(按照哈维的反应),我们能够同时启动多个进程,速度非常快。
如果我没有记错,而不是到Linux时,Windows从未被设计来快速启动多个进程。 这只是不是什么设计师还以为你会做-而在Linux上,有喜欢的东西inetd
等,它是一种常见的足够的经营模式,以保证优化-因此,创建进程进行了优化像地狱。
我测试你的代码中的Ubuntu 11.04戴尔Precision与4GB内存对这个结果:
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中有与创建许多Python的过程太困难。 运行之后p.start的500倍()就变得很慢。
有时候,我需要创建数千个很长一段时间的工作流程。
在实施例上面有不活过程的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
我尝试了140core服务器与SUSE Enterprise和我的笔记本电脑与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和较重的小 - 它需要的RAM第十绿带,并开始长一点。
文章来源: Need to create a large number of new processes very quickly in Windows/Python