为什么线程会增加处理时间?

2024-04-26 01:38:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我在做多任务处理一个基本的二维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线程实现,有没有一种方法可以让我真正的多任务处理?在


Tags: andto方法nameself列表is时间
3条回答

这是因为线程不会同时执行,因为GIL(全局解释器锁)的缘故,Python一次只能执行一个线程。在

当你生成一个新线程时,除了这个线程,所有的东西都会冻结。当它停止时,另一个被执行。生成线程需要很多时间。在

友好地说,代码根本不重要,因为任何使用100个线程的代码都比使用10个线程的Python中的代码慢(如果更多的线程意味着更高的效率和更高的速度,这并不总是真的)。在

以下是Python docs中的一句话:

CPython implementation detail:

In CPython, due to the Global Interpreter Lock, only one thread can execute Python code at once (even though certain performance-oriented libraries might overcome this limitation). If you want your application to make better use of the computational resources of multi-core machines, you are advised to use multiprocessing or concurrent.futures.ProcessPoolExecutor. However, threading is still an appropriate model if you want to run multiple I/O-bound tasks simultaneously.

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-packagemultiprocessing。在

相关问题 更多 >