系统命令的线程未 运行 并行

Threads not running in parallel for a system command

这是我的脚本

import threading
import os

class Say(threading.Thread):
    def __init__(self, cmd):
        super(Say, self).__init__()
        self.cmd = cmd
    def run(self):
        os.system(self.cmd)

t1 = Say("afplay /System/Library/Sounds/Tink.aiff")
t2 = Say("afplay /System/Library/Sounds/Ping.aiff")
t1.start()
print("a")
t2.start()
print("b")

看来两个启动都是立即执行的。但是,声音不是并行播放的,而是一个接一个播放的。

当运行宁以下shell脚本

afplay /System/Library/Sounds/Tink.aiff &
afplay /System/Library/Sounds/Ping.aiff &

两种声音同时播放。是什么让 Python 运行 命令顺序而不是并行?

我正在使用标准 Python (2.7) 的 Big Sur。

我怀疑这里的问题是 Python 的全局解释器锁 (GIL)。特别是我猜测当 os.systemt1 中被调用时,GIL 锁定并且直到命令 returns 才解锁,阻止 t2 来自 运行 任何 python 代码。

如果我替换

os.system(self.cmd)

subprocess.Popen(['bash', '-c', self.cmd])

然后问题就解决了。

就此而言,由于您在任何事件中都生成单独的进程并且对它们的输出不执行任何操作,因此创建所有这些线程是没有意义的;您可以通过将整个代码示例替换为

来获得相同的效果
import subprocess

subprocess.Popen(['bash', '-c', "afplay /System/Library/Sounds/Tink.aiff"])
subprocess.Popen(['bash', '-c', "afplay /System/Library/Sounds/Ping.aiff"])