我在做多任务处理一个基本的二维DLA模拟。扩散限制聚集(DLA)是当粒子执行随机行走时,当它们接触到当前聚集时聚集。在
在模拟中,我有10000个粒子在每一步都向随机方向移动。我用一堆工人和一队人来喂他们。我向他们提供一个粒子列表,工作人员对每个粒子执行.updatePositionAndggregate()
方法。在
如果我有一个工人,我给它一个10000个粒子的列表,如果我有两个工人,我给他们每人一个5000个粒子的列表,如果我有3个工人,我给他们每个3.333个粒子的列表,以此类推
我现在给你看一些工人的代码
class Worker(Thread):
"""
The worker class is here to process a list of particles and try to aggregate
them.
"""
def __init__(self, name, particles):
"""
Initialize the worker and its events.
"""
Thread.__init__(self, name = name)
self.daemon = True
self.particles = particles
self.start()
def run(self):
"""
The worker is started just after its creation and wait to be feed with a
list of particles in order to process them.
"""
while True:
particles = self.particles.get()
# print self.name + ': wake up with ' + str(len(self.particles)) + ' particles' + '\n'
# Processing the particles that has been feed.
for particle in particles:
particle.updatePositionAndAggregate()
self.particles.task_done()
# print self.name + ': is done' + '\n'
在主线中:
^{pr2}$所以,我打印出等待工人结束任务的平均时间。我用不同的线号做了一些实验。在
| num threads | average workers duration (s.) |
|-------------|-------------------------------|
| 1 | 0.147835636364 |
| 2 | 0.228585818182 |
| 3 | 0.258296454545 |
| 10 | 0.294294636364 |
我真的很想知道为什么增加工人会增加处理时间,我原以为至少有两个工人会减少处理时间,但它从0.14秒急剧增加到0.23秒。你能解释一下为什么吗?在
编辑: 所以,解释是Python线程实现,有没有一种方法可以让我真正的多任务处理?在
这是因为线程不会同时执行,因为GIL(全局解释器锁)的缘故,Python一次只能执行一个线程。在
当你生成一个新线程时,除了这个线程,所有的东西都会冻结。当它停止时,另一个被执行。生成线程需要很多时间。在
友好地说,代码根本不重要,因为任何使用100个线程的代码都比使用10个线程的Python中的代码慢(如果更多的线程意味着更高的效率和更高的速度,这并不总是真的)。在
以下是Python docs中的一句话:
Wikipedia about GIL
StackOverflow about GIL
这是由于Python的全局解释器锁。不幸的是,使用Python中的GIL,线程将阻塞I/O,因此永远不会超过1个CPU核心的使用量。{你已经开始理解了
检查正在运行的进程(例如,Windows中的taskmanager),会发现Python应用程序只使用了一个核心。在
我建议您看看Python中的多处理,它不受GIL:https://docs.python.org/2/library/multiprocessing.html的阻碍
python中的线程(至少在2.7中)不是同时执行的,因为GIL:https://wiki.python.org/moin/GlobalInterpreterLock-它们在单个进程中运行并共享CPU,因此不能使用线程来加速计算。在
如果您想使用并行计算来加速计算(至少在python2.7中),请使用processes-package
multiprocessing
。在相关问题 更多 >
编程相关推荐