Python多处理-如何提高效率
考虑以下两个简短的程序 正常_测试.py:Python多处理-如何提高效率,python,python-3.x,performance,multiprocessing,python-multiprocessing,Python,Python 3.x,Performance,Multiprocessing,Python Multiprocessing,考虑以下两个简短的程序 正常_测试.py: import time if __name__ == '__main__': t_end = time.time() + 1 loop_iterations = 0 while time.time() < t_end: loop_iterations += 1 print(loop_iterations) from multiprocessing import Process from mul
import time
if __name__ == '__main__':
t_end = time.time() + 1
loop_iterations = 0
while time.time() < t_end:
loop_iterations += 1
print(loop_iterations)
from multiprocessing import Process
from multiprocessing import Manager
import time
def loop1(ns):
t_end = time.time() + 1
while time.time() < t_end:
ns.loop_iterations1 += 1
def loop2(ns):
t_end = time.time() + 1
while time.time() < t_end:
ns.loop_iterations2 += 1
if __name__ == '__main__':
manager = Manager()
ns = manager.Namespace()
ns.loop_iterations1 = 0
ns.loop_iterations2 = 0
p1 = Process(target=loop1, args=(ns,))
p2 = Process(target=loop2, args=(ns,))
p1.start()
p2.start()
p1.join()
p2.join()
print(ns.loop_iterations1)
print(ns.loop_iterations2)
mp_test.py:
import time
if __name__ == '__main__':
t_end = time.time() + 1
loop_iterations = 0
while time.time() < t_end:
loop_iterations += 1
print(loop_iterations)
from multiprocessing import Process
from multiprocessing import Manager
import time
def loop1(ns):
t_end = time.time() + 1
while time.time() < t_end:
ns.loop_iterations1 += 1
def loop2(ns):
t_end = time.time() + 1
while time.time() < t_end:
ns.loop_iterations2 += 1
if __name__ == '__main__':
manager = Manager()
ns = manager.Namespace()
ns.loop_iterations1 = 0
ns.loop_iterations2 = 0
p1 = Process(target=loop1, args=(ns,))
p2 = Process(target=loop2, args=(ns,))
p1.start()
p2.start()
p1.join()
p2.join()
print(ns.loop_iterations1)
print(ns.loop_iterations2)
我希望在Raspberry Pi上使用Python多处理来并行读取多个ADC的值。因此,速度很重要。我运行这两个程序的笔记本电脑有四个内核,因此我无法理解为什么在第二个程序中创建的进程只能运行比第一个程序中的单个进程少近900倍的迭代次数。我是否错误地使用了Python多处理库?如何使流程更快
我是否错误地使用了Python多处理库
不正确?不,效率不高?对
请记住,多处理会创建协作的、但在其他方面是独立的Python实例。把他们想象成工厂里的工人,或是做大工作的朋友
如果只有一个人在一个项目上工作,那么这个人可以自由地在工厂里走动,拿起一个工具,使用它,放下它,移动到其他地方,拿起下一个工具,依此类推。再加上一个人,或者更糟的是,更多的人,也许甚至数百人,这个人现在必须协调:如果某个区域共享,或者某个工具共享,Bob不能只是去拿东西,他必须先问Alice她是否完成了
Manager
对象是Python多处理的通用共享包装器。将变量放入管理器名称空间意味着这些变量是共享的,因此在使用它们之前,请自动与其他人进行检查。(更准确地说,它们被保存在一个进程中的一个位置,并通过代理从其他进程访问或更改。)
在这里,你做了一个比喻,将“鲍勃:尽可能快地数数”替换为“鲍勃:不断打断爱丽丝问她是否在数数,然后数数;爱丽丝:数数,但总是被鲍勃打断。”到目前为止,鲍勃和爱丽丝的大部分时间都花在相互交谈上,而不是数数上
作为:
。。。在进行并发编程时,通常最好尽量避免使用共享状态。使用多个进程时尤其如此
(它以短语“如上所述”开头,但上面没有提到!)
有许多标准技巧,例如批处理以在共享事件之间完成大量工作,或者使用共享内存来加速共享,但使用共享内存时,您需要锁定项目。看起来是实现并行处理的更好方法(当不需要共享状态时)具有多处理队列
。OP的两个循环不需要共享状态
以下是测试
规格:
- Python版本:3.7.6李>
- 这台机器有两个2.3 GHz的Intel i-9 9880H CPU
当我执行问题中的normal_test.py
时,我得到:
$ python normal_test.py
7601322
然后我测试了多处理队列,如下所示(两个并行进程):
看起来并行运行两个进程比只运行一个进程能做更多的工作。用两个num1=Value('d',0.0)
替换名称空间可以改善它,但速度仍然较慢。问题可能是管理共享状态的开销#H4kor是的,不幸的是我需要共享状态,因为我有两个进程都需要访问的标志。那么我可能需要重新考虑我的设计。我知道我的问题中的程序不需要共享状态,但在我的实际代码中,我有两个进程都需要访问的全局标志。如果它们只需要读取访问,请复制。如果他们需要读写访问,考虑复制和批处理:例如,在标志没有改变的情况下生成1000个结果。然后,如果标志更改,则丢弃该工作并使用新标志重新开始。共享内存和管理器命名空间中的共享状态/变量之间有什么区别?@bgenchel:shared memory的字面意思是:不同的进程或线程写入同一内存,而无需在其他地方执行任何工作。这有正(快)和负(需要协调)。Python中的托管变量意味着变量的读写通过Python代码进行,而Python代码可以安排进行共享。这有优点(它只是工作,其他人做了所有的困难部分)和缺点(它非常慢)。@arun:多处理的意义。队列首先是避免使用共享内存进行通信。多处理。队列处理通信,而不依赖用户通过共享内存进行通信。这可以通过(相对)简单的编程获得正确性,有时会以性能为代价。如果队列
的性能不是一个问题,那么这很可能就是一条路。这样做容易得多。
import time
from multiprocessing import Process, Queue
def loop(n, q):
n_iter = 0
t_end = time.time() + 1
while time.time() < t_end:
n_iter += 1
q.put((n, n_iter))
if __name__ == '__main__':
results = []
q = Queue()
procs = []
for i in range(2):
procs.append(Process(target=loop, args=(i, q)))
for proc in procs:
proc.start()
for proc in procs:
n, loop_count = q.get()
results.append((n, loop_count))
for proc in procs:
proc.join()
del procs, q
for r in results:
print(r)
$ python multiproc2.py
(1, 10570043)
(0, 10580648)