我刚开始阅读有关多处理的内容,以加快我的程序速度。 因此,我写了两个基本的例子来从随机数列表中提取素数。
示例1:使用多处理
from multiprocessing import Process, Queue
from random import randrange
import time
def randomList(q, size, nmax):
l = []
r = randrange(2, nmax)
for i in range(size):
while r in l: # avoid replicating numbers
r = randrange(2, nmax)
l.append(r)
q.put(r)
def checkPrime(numbers, prime):
if numbers.qsize():
n = numbers.get()
count = 0 # divisors counter
d = 2 # divisor
while not count and d<=n/2:
if n%d:
d+=1
else:
count+=1
if not count:
prime.put(n)
if __name__=="__main__":
numbers = Queue()
prime = Queue()
randomList(numbers, 50, 1000) # 50 number | 100 max value
t1 = time.time()
while numbers.qsize():
for i in range(10): # Running 10 processes
p=Process(target=checkPrime, args=(numbers, prime))
p.start()
p.join()
t2 = time.time()
primes = []
for i in range(prime.qsize()):
primes.append(prime.get())
print("[+] Prime numbers:")
print(primes)
print("[+] Time elapsed:"+str(t2-t1))
输出:
[+] Prime numbers:
[17, 227, 389, 593, 953, 757]
[+] Time elapsed:9.41699981689
例2:相同的例子1但没有多处理
[...]
while numbers.qsize():
checkPrime(numbers, prime)
[...]
输出:
[+] Prime numbers:
[193, 227, 241, 439, 499, 877, 479, 743, 929]
[+] Time elapsed:0.00999999046326
因此,多处理使得这个程序(特别是可能)比没有使用它的速度慢很多。 任何解释?我用错了方法吗?
答案 0 :(得分:3)
我在想你的多处理方法很差。您不是将工作分成10个流程并立即启动它们,而是一次启动一个流程,每个流程都在执行单个工作单元,然后退出。您的实现将在其生命周期内创建(然后销毁)50个进程,这会产生大量开销。
您也可以在启动它们后立即加入这些流程,这将使您从未实际运行多个流程。连接使它等待子进程完成后再继续。
最后,还有一种更好的方法可以返回使用队列并一次获取单个值的结果。如果您可以使用一组工作立即启动每个进程,然后将列表中的结果返回到主线程,则可以减少使用队列的开销。
答案 1 :(得分:1)
当for i in range()
.join()
时,.join()
正在等待整个过程完成。因此,基本上,您正在生成一个新进程,该进程使用队列并报告结果,然后生成其他9个进程来检查空队列。
<强> map_async()
强>
阻止调用线程,直到调用join()方法的进程终止或者直到发生可选超时为止。
池是一种更简单的方法来做同样的事情。 检查此答案是否将{{1}}与工作人员一起使用:
答案 2 :(得分:1)
多处理中有一个简单的规则:如果用于分割(创建子任务)+加入(连接结果等)以创建多处理&gt;顺序时间然后你的“并行”版本相对于顺序版本将是低效的。这是你的情况。尝试生成一百万个数字(保持10个进程数),您将看到差异。
@ Sohcahtoa82的良好编码技巧。记住它们。