Python如何非阻塞执行代码,实现播放音乐时同步运行后续逻辑
问题根因
你的多线程/多进程代码写法存在基础错误:创建线程/进程对象时,target参数需要传入函数对象本身,不能加()调用函数。
你写的target=music()会在创建线程的瞬间就同步执行music()函数,等音乐播放完、函数返回结果后,才会继续执行后续创建线程、启动线程的逻辑,多线程完全没有生效,自然还是会阻塞。
可行修正方案
方案1:修正多线程写法(无需额外依赖)
把target后的函数括号去掉,传入函数名即可,建议把音乐线程设为守护线程,主程序退出时自动终止音乐播放,避免残留进程。
Windows环境下记得加if __name__ == "__main__":入口判断,避免多线程/进程运行异常。
import os import threading from playsound import playsound CurrentPath = os.path.dirname(os.path.normpath(__file__)) os.chdir(CurrentPath) def play_music(): playsound("Music.mp4") def run_business_logic(): print("Hello World") # 此处填写其余业务代码 if __name__ == "__main__": # 注意target后只写函数名,不要加括号 music_thread = threading.Thread(target=play_music, daemon=True) logic_thread = threading.Thread(target=run_business_logic) music_thread.start() logic_thread.start() # 等待业务逻辑执行完毕 logic_thread.join()
方案2:使用playsound自带非阻塞参数,无需手动写多线程
playsound原生支持非阻塞播放,只要给函数传入block=False参数,调用后会自动在后台播放音乐,不会阻塞后续代码执行,写法更简洁:
import os import time from playsound import playsound CurrentPath = os.path.dirname(os.path.normpath(__file__)) os.chdir(CurrentPath) if __name__ == "__main__": # 非阻塞启动背景音乐 playsound("Music.mp4", block=False) # 直接执行业务逻辑 print("Hello World") # 按需添加等待逻辑,避免主程序提前退出导致音乐中断 time.sleep(10) # 替换为你实际业务的运行时长控制逻辑
方案3:调用ffplay非阻塞播放
你之前注释的ffplay方案也可正常使用,把阻塞等待子进程结束的subprocess.run换成非阻塞的subprocess.Popen即可,启动播放器后会立刻返回执行后续代码:
import os import subprocess CurrentPath = os.path.dirname(os.path.normpath(__file__)) os.chdir(CurrentPath) if __name__ == "__main__": # 非阻塞启动ffplay隐藏窗口播放音乐 music_proc = subprocess.Popen( ["ffplay", "-nodisp", "-autoexit", "-hide_banner", "Music.mp4"], creationflags=subprocess.CREATE_NO_WINDOW # Windows下隐藏ffplay控制台窗口,Linux/macOS可删掉这行 ) # 执行业务逻辑 print("Hello World") # 业务结束后可手动终止ffplay进程 # music_proc.terminate()
避坑提示
- 所有传入
threading.Thread、multiprocessing.Process的target参数都不要加括号,否则会提前同步执行目标函数,多线程/多进程完全不生效。 - 非阻塞播放时要保证主程序在业务逻辑跑完前不退出,否则播放线程/子进程会被系统自动回收,出现音乐播放中断的问题。
- 使用多进程时Windows平台必须加
if __name__ == "__main__":入口判断,否则会出现递归启动程序的报错。
内容的提问来源于stack exchange,提问作者Z3r0ut
相关产品推荐
相关产品推荐

