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

Python多进程打包为EXE后运行异常问题排查求助

问题描述

我有一个基于PyQt5、OpenCV、多进程、串口库的项目,功能是根据串口传来的数据在屏幕上播放视频。项目在IDE中运行正常,但打包成EXE后运行异常。

创建多进程的代码片段

process_name = "p" + sequence_no_str
process = multiprocessing.Process(target=play_function, args=(screen, sequence_no, active_status), name=process_name)
process.start()
self.process_listesi.append(process)  # İşlem nesnesini listeye ekleme

因需同时播放多个视频,采用了多进程方案,对应的播放函数代码如下:

视频播放函数代码

def play_function(screen, sequence_no, active_status):
    print("Oynatma fonksiyonuna girdi")
    try:
        screen= int(screen)
        video = int(sequence_no)
        oynatma_durumu = int(active_status)
    except ValueError:
        print("Geçersiz girişler. Tüm değerler tamsayı olmalıdır.")
        return
        
    if screen< 1 or screen> 4:
        print("Geçersiz ekran numarası. 1 ile 4 arasında bir değer seçin.")
        return
        
    if video < 1 or video > 20:
        print("Geçersiz video numarası. 1 ile 8 arasında bir değer seçin.")
        return
        
    if oynatma_durumu == 1:
        # JSON dosyasını okuyun
        with open('config.json', 'r') as config_file:
            config_data = json.load(config_file)
            
        video_key = f"video{video}"  
        # Video yolu için config.json içindeki değeri alın
        video_name = config_data["videolar"][video_key]  
                
        # Video yolunu oluşturun
        video_path = os.path.join(os.path.dirname(__file__), "videolar", video_name)
        cap = cv2.VideoCapture(video_path)
        fps = int(cap.get(cv2.CAP_PROP_FPS))

        if not cap.isOpened():
            print(f"Video açılamadı: {video_path}")
            return
            
        cv2.namedWindow(f"screen{screen}", cv2.WND_PROP_FULLSCREEN)
        cv2.setWindowProperty(f"screen{screen}", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)

        while True:
            ret, pencere = cap.read()
            if not ret:
                print(f"Video sona erdi: {video_path}")
                # Video sonuna geldiğinde başa dön
                cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
                continue

            cv2.imshow(f"screen{screen}", pencere)
                
            # Videonun hızını ayarlamak için bekleme süresini hesaplayın
            wait_time = int(1000 / (fps*4))  # Milisaniye cinsinden bekleme süresi hesaplaması

            key = cv2.waitKey(wait_time)
            if key == ord('q'):
                break
            
        cap.release()
    elif oynatma_durumu == 0:
        print("video durduruldu")
        cv2.destroyWindow(f"screen{screen}")
问题排查方向

一、代码实现层面的潜在问题

  • 资源路径错误:打包成EXE后,os.path.dirname(__file__)指向的是EXE解压后的临时目录,而非原项目目录,会导致找不到config.json和视频文件。可以改用sys._MEIPASS获取PyInstaller打包后的资源临时路径,确保资源访问正确。
  • 多进程启动规范:Windows系统下,多进程必须在if __name__ == '__main__':代码块内启动,否则会重复初始化进程,引发异常。
  • CV2窗口兼容性:OpenCV窗口在多进程环境中存在线程安全问题,打包后可能出现窗口无法渲染、崩溃等情况。建议主进程管理窗口,子进程仅负责读取视频帧并传递给主进程显示。
  • 进程状态管理:传入的active_status是静态参数,子进程无法感知外部状态变化,当前的停止逻辑无法终止正在运行的播放循环,会导致进程残留。

二、打包为EXE时的注意事项

  • 资源文件打包:必须通过PyInstaller的--add-data参数指定资源文件路径,例如:
    pyinstaller --onefile --add-data "config.json;." --add-data "videolar;videolar" your_script.py
    
  • 依赖库与DLL文件:确保OpenCV的依赖DLL(如opencv_worldxxx.dll)、串口库相关文件被正确打包,必要时用--hidden-import指定缺失模块。
  • 多进程控制台设置:如果不需要控制台窗口,使用--noconsole参数;需要日志输出时,保留控制台,避免子进程无法输出调试信息。
  • 运行权限:打包后的EXE需以管理员权限运行,否则可能无法访问串口或获取全屏窗口权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 12:05:53