pyinstaller - pool.apply_async 不调用目标函数,pyinstaller 打包后调用主函数
问题描述
我使用 Pool.async 执行卸载软件功能。如果不打包为 exe,它运行良好。但是当我将它打包为exe时,它不是调用目标函数而是调用主函数。这是我的代码。
if __name__ == '__main__':
print("main function called")
try:
# 使用文件锁,限制单进程
parent_folder = "C:\\Program Files (x86)\\ctyun\\eCloudDeskDRT\\sdk"
if not os.path.exists(parent_folder):
os.makedirs(parent_folder)
lock_file_name = 'eCloudDeskDRTSrv.lock'
lock_file_path = os.path.join(parent_folder, lock_file_name)
lock_file_fd = open(lock_file_path, 'w')
portalocker.lock(lock_file_fd, portalocker.LOCK_EX | portalocker.LOCK_NB)
lock_file_fd.writelines(str(os.getpid()))
lock_file_fd.flush()
except BaseException as e:
print("CloudDeskDRTSrv.exe have another instance running.")
sys.exit()
def uninstall_software_sub(software_name, uninstall_string, uninstall_process_name):
try:
log_utils.get_logger().info('uninstall_software_sub')
startupinfo = sp.STARTUPINFO()
startupinfo.dwFlags |= sp.STARTF_USESHOWWINDOW
popen = sp.Popen(uninstall_string, stdout=sp.PIPE, stdin=sp.PIPE, stderr=sp.STDOUT, startupinfo=startupinfo)
log_utils.get_logger().info(popen.pid)
b_cmd = uninstall_string.encode("UTF-8")
log_utils.get_logger().info("execute command %s", uninstall_string)
b_outs, errs = popen.communicate(b_cmd, timeout=None)
if uninstall_process_name:
while windows_utils.check_process_running(uninstall_process_name):
time.sleep(3)
else:
popen.wait()
log_utils.get_logger().info("wait finished")
outs = b_outs.decode('gbk', 'ignore')
if errs:
log_utils.get_logger().error(errs)
else:
log_utils.get_logger().info(outs)
except UnicodeDecodeError as error:
log_utils.get_logger().exception(error)
outs = ""
finally:
if not popen.poll():
popen.kill()
uninstall_software_info = get_uninstall_software_info(software_name)
uninstall_success = uninstall_software_info is None
return uninstall_success
def uninstall_software(software_name, uninstall_callback):
log_utils.get_logger().info("uninstall_software software_name=%s", software_name)
uninstall_info = get_uninstall_software_info(software_name)
uninstall_string = uninstall_info.uninstall_string
if software_name in uninstall_process.keys():
uninstall_process_name = uninstall_process.get(software_name)
log_utils.get_logger().info(os.getpid())
pool = Pool(1)
log_utils.get_logger().info('apply_async')
pool.apply_async(func=third_party_software_check.uninstall_software_sub,
args=(software_name, uninstall_string, uninstall_process_name),
callback=uninstall_callback)
unisntall_software_sub 不执行,但执行 pool.apply_async 时会调用 main 函数。这是日志输出。有人可以帮助我吗?
解决方案
我发现 pyinstaller 支持多处理。但是需要在源代码中添加一些命令。我在主函数下方添加了 multiprocessing.freeze_support() 。它工作得很好。这是源代码:
if __name__ == '__main__':
print("main function called")
multiprocessing.freeze_support()
try:
# 使用文件锁,限制单进程
parent_folder = "C:\\Program Files (x86)\\ctyun\\eCloudDeskDRT\\sdk"
if not os.path.exists(parent_folder):
os.makedirs(parent_folder)
lock_file_name = 'eCloudDeskDRTSrv.lock'
lock_file_path = os.path.join(parent_folder, lock_file_name)
lock_file_fd = open(lock_file_path, 'w')
portalocker.lock(lock_file_fd, portalocker.LOCK_EX | portalocker.LOCK_NB)
lock_file_fd.writelines(str(os.getpid()))
lock_file_fd.flush()
except BaseException as e:
print("CloudDeskDRTSrv.exe have another instance running.")
sys.exit()
推荐阅读
- javascript - expressGraphQL 不是函数
- html - CSS中是否有任何方法可以将元素与兄弟的最终行框的末尾对齐?
- python - 用 Python 制作 exe 文件,包括数据库
- spring - 是否必须仅在子模块中添加 spring-boot-starter-* 依赖项?
- c# - C#如何使用Autofac注册httpcontextbase
- node.js - 我的 nginx 配置对我有什么好处吗?我什至需要代理通行证吗?
- swagger - 使用外部 .yaml 文件在 openapi3.0 yaml 中添加模式定义
- python - 如何从烧瓶中的嵌套 if statmant 传递值?
- javascript - 反应本机 foreach 循环无法正常工作
- flutter - 如何在颤振中添加自动填充下拉菜单?