多语言展示
当前在线:1886今日阅读:86今日分享:14

python while True造成未响应或卡顿的解决方法

使用多线程时,常在主线程使用while True循环等待子线程返回数据,但由于while True是“死循环”,会造成主程序卡顿,未响应。现经过实践,提出一个解决办法。
方法/步骤
1

以一个程序为例:一般遇到耗时重载的工作,我们采用单线程会造成程序未响应,卡顿现象,所以通过主线程中开启一个子线程,子线程负责耗时的处理工作,两者之间通过queue通信,避免单线程卡顿。

2

代码片段为:主线程:前面要开启一个主窗口root_window,然后进入到调用子线程que = Queue.Queue()#消息队列th1=threading.Thread(target=th_work)#设定子线程th1.setDaemon(True)#守护线程th1.start()#开启子线程while True: #循环等待子线程返回数据    if not que.empty():       mes = que.get()       if mes == u'end_tag': #接收到结束码,就结束          break       textmessage.insert(END,mes)       textmessage.see(END)       textmessage.update()子线程:代码略,负责处理耗时重载工作,通过que返回数据,如果工作完成,向que推入u'end_tag',通知主线程工作完成。

3

上面的代码运行时发现,程序仍然出现卡顿的现象,通过关闭while true循环的测试发现,此时卡顿是while true死循环遇到长时间接收不到que信息时造成的。

4

本人在网上搜索后发现,有人建议添加sleep,如下:主线程:前面要开启一个主窗口root_window,然后进入到调用子线程que = Queue.Queue()#消息队列th1=threading.Thread(target=th_work)#设定子线程th1.setDaemon(True)#守护线程th1.start()#开启子线程while True: #循环等待子线程返回数据    if not que.empty():       mes = que.get()       if mes == u'end_tag': #接收到结束码,就结束          break       textmessage.insert(END,mes)       textmessage.see(END)       textmessage.update()    else:      time.sleep(1)但是卡顿仍然出现。

5

经过一段时间的摸索和实验,本人发现,可以采用update的方法来避免卡顿,代码如下:主线程:前面要开启一个主窗口root_window,然后进入到调用子线程que = Queue.Queue()#消息队列th1=threading.Thread(target=th_work)#设定子线程th1.setDaemon(True)#守护线程th1.start()#开启子线程while True: #循环等待子线程返回数据    if not que.empty():       mes = que.get()       if mes == u'end_tag': #接收到结束码,就结束          break       textmessage.insert(END,mes)       textmessage.see(END)       textmessage.update()    else:       root_window.update()#这里的root_window是主程序的窗口。     这段代码的意思是:等待子线程返回的信息,并在主窗口的textmessage(是一个scrolledtext控件)显示处理结果,在子线程处理耗时,一时没有返回信息(que为空)的时候主线程一边等待,一边采用root_window.update()刷新主窗口,在收到结束码u'end_tag'时,表示子线程工作完成,结束程序。     这样处理后,程序完全不卡顿,不会出现未响应的状况,也可以自由的移动主窗口,最大化最小化主窗口也不会卡顿。亲测有效。

推荐信息