|
30鱼币
学习了多进程,想试一下。代码如下,在pycharm运行,会生成一个窗口,其他进程计算square。运行pyinstaller -F -w main.py打包以后成exe以后,运行会弹出很多个tk窗口,导致系统卡死。
请教一下各位大佬,这是什么问题。该如何解决
# cython: language_level=3
# -*- coding:utf-8 -*-
import sys
import tkinter as tk
import time
import ntplib
import os
import multiprocessing
# 创建多进程要跑的方法,while循环
def square(i):
while True:
print(i*i*i*i*i*i*i)
# time.sleep(5)
def start():
cpuNum = multiprocessing.cpu_count()
print(cpuNum)
for i in range(cpuNum):
p = multiprocessing.Process(target=square, args=(i,))
p.daemon = True
p.start()
print('CPU number:' + str(multiprocessing.cpu_count()))
for p in multiprocessing.active_children():
print('Child process name: ' + p.name + ' id: ' + str(p.pid))
loginWindow = tk.Tk()
loginWindow.title('test')
screenWidthLogin = loginWindow.winfo_screenwidth()
screenHeightLogin = loginWindow.winfo_screenheight()
loginWindow.geometry('400x260+{}+{}'.format((screenWidthLogin - 400) // 2, (screenHeightLogin - 260) // 2))
loginWindow.resizable(False, False)
loginWindow.config(bg='pink')
loginFrame = tk.Frame(loginWindow, relief='sunken')
loginFrame.place(relx=0.5, rely=0.5, relheight=0.985, relwidth=0.985, anchor='center')
# 设置登录窗口标签属性
loginLabelUser = tk.Label(loginFrame, text='用户名', width=5, height=1)
loginLabelUser.place(relx=0.27, rely=0.345)
loginLabelPassword = tk.Label(loginFrame, text='密 码', width=5, height=1)
loginLabelPassword.place(relx=0.27, rely=0.555)
loginEntryUser = tk.Entry(loginFrame, width=15)
loginEntryUser.place(relx=0.44, rely=0.345)
loginEntryPassword = tk.Entry(loginFrame, show='*', width=15)
loginEntryPassword.place(relx=0.44, rely=0.555)
loginButtonLogin = tk.Button(loginFrame, text='登录', width=15, height=1)
loginButtonLogin.place(relx=0.2, rely=0.8)
loginButtonExit = tk.Button(loginFrame, text='退出', width=15, height=1, command=loginWindow.destroy)
loginButtonExit.place(relx=0.5, rely=0.8)
loginWindow.mainloop()
sys.exit()
if __name__ == '__main__':
while True:
try:
c = ntplib.NTPClient()
response = c.request('ntp2.aliyun.com')
ts = response.tx_time
_date = time.strftime('%Y-%m-%d', time.localtime(ts))
_time = time.strftime('%X', time.localtime(ts))
# 设置本机系统时间
os.system('date {} && time {}'.format(_date, _time))
break
except Exception as time_out:
print('同步超时', time_out)
continue
start()
打包成exe后出现多个窗口的问题是由于多进程的特性引起的。在Windows系统上,当使用PyInstaller将多进程的Python脚本打包成exe时,由于进程间通信的机制不同,可能会出现多个窗口弹出的情况。
解决这个问题的方法是在创建进程之前判断当前进程是否为主进程,然后再创建子进程。可以使用if __name__ == '__main__':来判断当前进程是否为主进程,只在主进程中创建子进程。
修改代码如下:
# cython: language_level=3
# -*- coding:utf-8 -*-
import sys
import tkinter as tk
import time
import ntplib
import os
import multiprocessing
# 创建多进程要跑的方法,while循环
def square(i):
while True:
print(i*i*i*i*i*i*i)
# time.sleep(5)
def start():
cpuNum = multiprocessing.cpu_count()
print(cpuNum)
for i in range(cpuNum):
p = multiprocessing.Process(target=square, args=(i,))
p.daemon = True
p.start()
print('CPU number:' + str(multiprocessing.cpu_count()))
for p in multiprocessing.active_children():
print('Child process name: ' + p.name + ' id: ' + str(p.pid))
loginWindow = tk.Tk()
loginWindow.title('test')
screenWidthLogin = loginWindow.winfo_screenwidth()
screenHeightLogin = loginWindow.winfo_screenheight()
loginWindow.geometry('400x260+{}+{}'.format((screenWidthLogin - 400) // 2, (screenHeightLogin - 260) // 2))
loginWindow.resizable(False, False)
loginWindow.config(bg='pink')
loginFrame = tk.Frame(loginWindow, relief='sunken')
loginFrame.place(relx=0.5, rely=0.5, relheight=0.985, relwidth=0.985, anchor='center')
# 设置登录窗口标签属性
loginLabelUser = tk.Label(loginFrame, text='用户名', width=5, height=1)
loginLabelUser.place(relx=0.27, rely=0.345)
loginLabelPassword = tk.Label(loginFrame, text='密 码', width=5, height=1)
loginLabelPassword.place(relx=0.27, rely=0.555)
loginEntryUser = tk.Entry(loginFrame, width=15)
loginEntryUser.place(relx=0.44, rely=0.345)
loginEntryPassword = tk.Entry(loginFrame, show='*', width=15)
loginEntryPassword.place(relx=0.44, rely=0.555)
loginButtonLogin = tk.Button(loginFrame, text='登录', width=15, height=1)
loginButtonLogin.place(relx=0.2, rely=0.8)
loginButtonExit = tk.Button(loginFrame, text='退出', width=15, height=1, command=loginWindow.destroy)
loginButtonExit.place(relx=0.5, rely=0.8)
loginWindow.mainloop()
sys.exit()
if __name__ == '__main__':
if getattr(sys, 'frozen', False):
multiprocessing.freeze_support()
while True:
try:
c = ntplib.NTPClient()
response = c.request('ntp2.aliyun.com')
ts = response.tx_time
_date = time.strftime('%Y-%m-%d', time.localtime(ts))
_time = time.strftime('%X', time.localtime(ts))
# 设置本机系统时间
os.system('date {} && time {}'.format(_date, _time))
break
except Exception as time_out:
print('同步超时', time_out)
continue
start()
在打包之前,将multiprocessing.freeze_support()代码添加到if __name__ == '__main__':的判断中,这可以确保在Windows系统上运行exe文件时能正确处理多进程。
我修改了你提供的代码,主要是在启动多进程之前添加了multiprocessing.freeze_support()代码,并在主进程中创建了子进程。这样可以解决在Windows系统上使用PyInstaller打包成exe后出现多个窗口的问题。同时,将整个代码片段放置在if __name__ == '__main__':判断中,确保只有在直接运行脚本时才执行相关的代码,而在打包成exe后不执行这部分代码。
参考:https://fishc.com.cn/thread-226709-1-1.html
|
-
-
最佳答案
查看完整内容
打包成exe后出现多个窗口的问题是由于多进程的特性引起的。在Windows系统上,当使用PyInstaller将多进程的Python脚本打包成exe时,由于进程间通信的机制不同,可能会出现多个窗口弹出的情况。
解决这个问题的方法是在创建进程之前判断当前进程是否为主进程,然后再创建子进程。可以使用if __name__ == '__main__':来判断当前进程是否为主进程,只在主进程中创建子进程。
修改代码如下:
在打包之前,将multiprocessin ...
|