【问题标题】:Why do these threads fail to work in parallel?为什么这些线程不能并行工作?
【发布时间】:2020-11-17 21:58:54
【问题描述】:

为什么这段代码不能并行工作?

当奇数线程开始计算它的大数时,其他线程出于某种原因只是等待它完成,尽管它们应该做自己的事情。我错过了什么?

import threading, math, time

class MyThread(threading.Thread): 

    def __init__(self, num):
        super(MyThread, self).__init__()
        self.num = num
        
    def run(self):
        while True:
            with mutex:
                print(self.num, 'started')
            math.factorial(self.num % 2 * 100000000)
            with mutex:
                print(self.num, 'finished')
            time.sleep(2)

mutex = threading.Lock()
threads = [MyThread(i) for i in range(5)]
for th in threads:
    th.start()

【问题讨论】:

  • 你知道GlobalInterpreterLock吗?可能是您需要使用多处理而不是线程,这可以真正并行执行。
  • 不幸的是,我只能使用多线程
  • 那是关键信息,你为什么没有在你的帖子中提到它?你肯定需要包括这个(以及任何理由),因为你会浪费每个人的时间,他们会尝试建议多处理。

标签: python multithreading python-multithreading


【解决方案1】:

Python 线程实际上并没有引入真正的并行性。由于 GIL(全局解释器锁),每个处理器内核只能有一个解释器线程。见GlobalInterpreterLock

正在发生的事情是工作被分配给您的各个线程,然后它们在 GIL 上一次执行一个。引用realpython.com的An Intro to Threading in Python

线程是一个独立的执行流程。这意味着您的程序将同时发生两件事。但是对于大多数 Python 3 实现来说,不同的线程实际上并不会同时执行:它们只是看起来。

要实现真正的并行性,您必须使用 multiprocessing 库,它将:

通过使用子进程而不是线程来有效地避开全局解释器锁。因此,多处理模块允许程序员充分利用给定机器上的多个处理器。

【讨论】:

  • 不幸的是,由于某些未指定的原因,OP“只能使用多线程”。
【解决方案2】:

此行为与 cPyhton 特定的实现细节有关(使用其他答案中解释的全局解释器锁)

但是,当使用 jython(Python 的 Java 实现)运行此脚本时,您会得到预期的结果。

$ jython main.py
(0, 'started')
(2, 'started')
(3, 'started')
(1, 'started')
(4, 'started')
(0, 'finished')
(2, 'finished')
(4, 'finished')
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-18
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    相关资源
    最近更新 更多