简体   繁体   中英

Threads not running in parallel for a system command

This is my script

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")

It appears that both starts are executed immediately. However, the sounds are not played in parallel but one after the other.

When running the following shell script

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

both sounds play at the same time. What makes Python run the commands sequentially instead of parallel?

I'm using Big Sur with with the standard Python (2.7).

I suspect the issue here is Python's Global Interpreter Lock (GIL). In particular I'm guessing that when os.system is called in t1 , the GIL locks and doesn't unlock until the command returns, preventing t2 from running any python code.

If I replace

os.system(self.cmd)

with

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

then the problem goes away.

For that matter, since you are spawning separate processes at any event and doing nothing with their output, there is no point in creating all these threads; you can get the same effect by replacing your entire code sample with

import subprocess

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM