You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyInstaller打包Python RPG程序出现多实例问题的解决求助

PyInstaller打包Python RPG游戏后出现多实例运行问题

我用Python开发了一款RPG游戏,为了给没有Python环境的朋友展示进度,用PyInstaller把脚本打包成了.exe文件。但测试时发现程序会多实例运行,我怀疑这和使用multiprocessing模块有关,但不知道怎么用freeze_support()解决这个问题。最终我改用threading和pygame替代multiprocessing与playsound,解决了问题。

原始代码

import random
import os
import sys
import time
from playsound import playsound
import multiprocessing

class Unit:
    def __init__(self, name, hp, strength, defense):
        self.name = name
        self.hp = hp
        self.strength = strength
        self.defense = defense

    def __str__(self):
        return f"""Name: {self.name}
HP  : {self.hp}   
STR : {self.strength} 
DEF : {self.defense} \n"""
    
    def attack(self, enemy):
        input("Press Enter to continue \n")
        print(f"{self.name} attacks {enemy.name}!")
        randomVariable = random.randint(0, 100)
        if randomVariable < 70:
            damage = self.strength - enemy.defense
            damage = notLessZero(damage)
            print(f"{self.name} hits {enemy.name} for {damage}!")
            enemy.hp -= damage
            enemy.hp = notLessZero(enemy.hp)
            print(enemy)
        else:
            print("Miss!")

def notLessZero(variable):
    return max(0, variable)

def battle(playerUnit, enemyUnit):
    while enemyUnit.hp > 0:
        playerUnit.attack(enemyUnit)

def loopingMusic(soundFile):
    while True:
        playsound("music/cats.wav")

def main():
    name = input("What's your name? \n")
    print("a")
    p = multiprocessing.Process(target=loopingMusic, args=("cats.wav",))
    p.start()
    print("b")
    playerUnit = Unit(name, 5, 6, 2)
    enemyUnit = Unit("Enemy", 5, 2, 3)
    print("c")
    print(playerUnit)
    print(enemyUnit)
    print("d")
    battle(playerUnit, enemyUnit)
    print("e")
    p.terminate()
    print("f")
    playsound('music/riff.wav', block = False)
    print("g")
    print("Enemy defeated\n")
    input("Congatulations\n")

if __name__ == '__main__':
    sys.exit(main())

问题原因

在Windows系统下,PyInstaller打包带有multiprocessing的脚本时,会因进程启动机制触发多实例问题。Windows没有fork系统调用,multiprocessing需通过重新导入主模块创建子进程,打包后的exe在导入时会重复执行主程序逻辑,导致多实例运行。

用freeze_support()的解决方式

如果要继续使用multiprocessing,需在主入口最开始位置添加multiprocessing.freeze_support(),修改后的主入口代码如下:

if __name__ == '__main__':
    multiprocessing.freeze_support()
    sys.exit(main())

该函数会告知multiprocessing当前处于打包后的环境,避免重复启动主程序实例。

最终采用的替代方案

由于对freeze_support()的应用不熟悉,我改用threading线程来处理循环音乐播放,同时用pygame替代playsound处理音频,既规避了多进程带来的打包问题,也实现了音乐循环播放的需求。

内容的提问来源于stack exchange,提问作者Nabil Darwish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 04:09:57