【发布时间】:2020-11-23 22:49:37
【问题描述】:
我是 python 新手,遇到了一些问题。
我编写了一个 update_manager 类,它可以通过 Tcp 与用户进行通信,并预先安装不同的组件。
我的 update_manager 类使用 2 个其他类(它们是他的成员)来完成此操作。第一个用于 TCP 通信,第二个用于实际安装。安装类从主线程运行,通过Threading.thread()函数进行通信。
我的 main 锁是这样的:
if __name__ == "__main__":
new_update = UpdateManager()
#time.sleep(10)
new_update.run()
运行函数为:
def run(self):
comm_thread = threading.Thread(target=
self._comm_agent.start_server_tcp_comunication)
comm_thread.start()
while True:
if (False == self.is_recovery_required()):
self.calculate_free_storage_for_update_zip_extraction()
self.start_communication_with_client_in_state_machine()
self._comm_agent.disable_synchronized_communication()
self.start_update_install()
self._comm_agent.enable_synchronized_communication()
if (True == self.is_dry_run_requested()):
self.preform_cleanup_after_dry_run()
else:
self.reset_valid_states()
self.preform_clean_up_after_update_cycle()
我使用 2 multiprocessing.Queue() 在线程之间和用户之间进行同步。一个用于传入消息,一个用于传出消息。
起初TCP通信是同步的,用户提供安装文件和其他一些东西。
安装开始后,TCP 通信不再同步。
在安装过程中,我使用了 4 种不同的安装方法。并且除了一个之外的所有工作都没有问题(用户可以汇集 update_manager 进程并提出进度问题并立即得到答复)
问题之一是 rpm 文件的实例化。为此,我尝试调用 os.system() 和 subprocess.run() 并且它可以工作,但是对于大 rpm 文件,我注意到我的线程的整个过程冻结直到 通话结束(在冻结期间我可以在屏幕上看到 rpm 安装的进度条)。
我注意到并尝试过的: 1.其他使用python的安装方法没有冻结。 图书馆。
2.一旦用户通过 TCP 连接,update_manager 只有 2 个线程,一旦发送第一个请求并发送回回复,就会出现另外 2 个线程(我认为这与我使用的队列有关)。
3.我创建了第三个打印时间的线程(与队列无关),并且在 update_manager 进程启动后立即启动它。当 2 个线程冻结时,这个会继续运行。
4.在极少数情况下,进程会解冻,只是为了让消息从客户端发送到 update_manager 并冻结回来。
编辑:我忘记了更重要的一点 5.调用时出现冻结: os.system("rpm --nodeps --force -ivh rpm_file_name")
但调用时不会发生: os.system("睡眠 5")
我真的很感激一些穷人,谢谢。
【问题讨论】:
-
还有一件事,当我尝试将 update_manager 的简单版本编写为一个具有 2 个功能(一个打印内容和一个安装 rpm 文件)的类时,没有队列,也没有 TCP。使用相同的 threading.thread() 它可以工作。
标签: python multithreading subprocess message-queue