我翻译C++ renderer
成Python
。所述C++
渲染器使用螺纹,每个渲染的图像的一部分。我想在中做同样的事情Python
。不过,看来,我的多线程代码版本需要年龄相比,我的单线程代码版本。我是多处理新手,Python
因此想知道下面的代码是否真正符合我的想法:创建线程池,添加并执行一些任务并等待所有任务完成?
我知道我无法与我的C++
版本竞争,但我希望Python
至少能打败单线程版本。
多线程代码
from multiprocessing.pool import ThreadPool
pool = ThreadPool(processes=4)
pool.map(run_task(...), range(11))
pool.close()
pool.join()
单线程代码
for i in range(11):
Task(...)(i)
任务代码
def run_task(...):
task = Task(...)
return task.__call__
class Task():
def __init__(self, ...):
...
def __call__(self, i):
...
编辑:我尝试使用from multiprocessing import Pool
。这似乎使我的Python
终端无法进入Canopy IDE
。当我从Windows命令行运行文件时,我收到:
C:\Users\Matthias\Documents\Courses\Masterproef\pbrt\Tools\Permeability\src>pyth
on renderer.py
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Users\Matthias\AppData\Local\Enthought\Canopy\App\appdata\canopy-1.5.
2.2785.win-x86_64\lib\threading.py", line 810, in __bootstrap_inner
self.run()
File "C:\Users\Matthias\AppData\Local\Enthought\Canopy\App\appdata\canopy-1.5.
2.2785.win-x86_64\lib\threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "C:\Users\Matthias\AppData\Local\Enthought\Canopy\App\appdata\canopy-1.5.
2.2785.win-x86_64\lib\multiprocessing\pool.py", line 342, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin_
_.instancemethod failed
(这也是为什么我通常更喜欢线程而不是进程。因此,GIL设计决策对我而言并不真正有意义。)
您应该使用进程池而不是线程池(请参阅此处的第一个示例)。
由于CPython的GIL,不应将多线程用于CPU绑定任务。
也许这个简短的示例会有所帮助(我们称之为example.py
):
from multiprocessing import Pool
import sys
if __name__ == '__main__':
job_list = [xrange(10000000)]*6
if 'p' in sys.argv:
p = Pool(2)
print("Parallel map")
print(p.map(sum, job_list))
else:
print("Sequential map")
print(map(sum, job_list))
我的机器有2个内核,example.py p
(并行)版本的速度是顺序内核的两倍。如果我们减少要完成的工作量(从十个数字而不是一千万个数字求和),则顺序版本会获胜,因为在并行版本中创建流程和委派任务会产生不必要的开销。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句