[忤旭]《Python》多線程手動控制循環(huán)任務(wù)
大家好,我是忤旭!
今天分享的內(nèi)容是利用多線程手動控制循環(huán)任務(wù)以及函數(shù)體的帶參調(diào)用。多線程手動控制循環(huán)任務(wù)針對的問題是如何手動對某一線程中循環(huán)的任務(wù)進行控制;函數(shù)體的帶參調(diào)用是指在調(diào)用函數(shù)體時如何傳入?yún)?shù)。下面直接看代碼來進行分析
代碼(Python 3.8)
import tkinter
import threading
import time
exitflag = False
def thread_task():
? global exitflag
? while True:
? ? ?if button1['text'] == '暫停':
? ? ? ? print('線程工作中')
? ? ?else:
? ? ? ? print('線程停止中')
? ? ?time.sleep(1)
? ? ?if exitflag == True:
? ? ? ? root.quit()
? ? ? ? print('線程任務(wù)已結(jié)束')
? ? ? ? break
thread = threading.Thread(target = thread_task)
root =tkinter.Tk()
def on_off():
? if button1['text'] == '暫停':
? ? ?button1['text'] = '開始'
? else:
? ? ?button1['text'] = '暫停'
button1 = tkinter.Button(root, text = '暫停', command = on_off, bg = 'White', fg = 'black',
? ? ? ? ? ? ? ? ? ? ? ? font = ("楷體", 24), width = 10, height = 2)
def single_print(num):
? global number
? print(num)
? number += 1
number = 0
button2 = tkinter.Button(root, text = '單步打印', command = lambda: single_print(number), bg = 'White', fg = 'black',
? ? ? ? ? ? ? ? ? ? ? ? font = ("楷體", 24), width = 10, height = 2)
def exit():
? global exitflag
? exitflag = True
button3 = tkinter.Button(root, text = '退出', command = exit, bg = 'White', fg = 'black',
? ? ? ? ? ? ? ? ? ? ? ? font = ("楷體", 24), width = 10, height = 2)
button1.pack()
button2.pack()
button3.pack()
thread.start()
root.mainloop()
print('正在等待線程結(jié)束...')
thread.join()
print('所有線程已退出')
分析
問題:你希望手動停止一個循環(huán),但該線程已經(jīng)被這個循環(huán)阻塞,無法進行后續(xù)操作,但又不想在循環(huán)中插入影響循環(huán)的鍵盤輸入。
解決方法:在原有線程中,加入一個判斷標志,并另開一個線程來控制該判斷標志。
如代碼中所示,線程thread的任務(wù)是thread_task(),并且該任務(wù)是無限循環(huán),運行結(jié)果如圖所示

于是創(chuàng)建一個界面(用到tkinter),該界面實際上是另一個線程。上面有3個按鍵,分別為開始/暫停、單步打印和結(jié)束,3者對應(yīng)的函數(shù)體分別為on_off、single_print和exit。

分析分別按下3個按鍵會發(fā)生的情況
當按下開始/暫停時,調(diào)用on_off()函數(shù)的函數(shù)體,該函數(shù)會更改開始/暫停鍵上的文字內(nèi)容,而觀察thread_task()函數(shù)中,可以看到循環(huán)中有判斷標示為開始/暫停鍵上的文字內(nèi)容,這樣就可以實現(xiàn)手動控制另一個線程中的循環(huán)。

當按下退出時,調(diào)用exit()函數(shù)的函數(shù)體,該函數(shù)會更改全局變換exitflag的值,從而令thread_task()可以在檢測到exitflag值為True時,結(jié)束循環(huán)。

當按下單步打印時,利用lambda:single_print(number)帶參調(diào)用single_print()函數(shù)的函數(shù)體,就可以實現(xiàn)向single_print()函數(shù)的函數(shù)體傳入?yún)?shù)number,可以在下圖中看到參數(shù)被打印并且可變。
