![](/img/trans.png)
[英]python | tkinter and threading: “main thread is not in main loop”
[英]Python Threading - Managing thread termination and the main thread
在你繼續閱讀之前,要知道我是Python新手並且對線程很新,所以請原諒我,如果我誤解了線程的工作方式或新手錯誤:P
我的目標的簡短描述:
這是我到目前為止(基礎知識):
import threading, time
def printCount():
print "Thread B started"
x = 0
while True:
time.sleep(1)
x = x + 1
print x
## User Code ##
print "begin!"
threadB = threading.Thread(target=printCount)
threadB.start()
print "woop!"
要求是:
except
KeyboardInterrupt: os._exit(1))
except
KeyboardInterrupt: os._exit(1))
except
KeyboardInterrupt: os._exit(1))
用戶代碼里面很好 這個例子不是我的實際目標,只是我遇到的問題的簡化版本。 我正在嘗試創建一個IRC框架,用戶可以在其中導入它並非常簡單地使用API,而不會使用線程和中斷等來清除自己的代碼。 這就是為什么用戶代碼盡可能干凈是很重要的。
該框架將允許用戶創建一個永遠運行的IRC機器人,在允許用戶添加自己的命令的同時監聽命令。 如果您感興趣的話,Github鏈接就在這里 (這是非常重要的WIP)。
在昨天的另一個問題上寫了一個關於類似問題的簡短說明,這是你可以在子線程“b”中實現的檢查:
而不是while 1:
執行以下操作:
def printCount():
main = None
for t in threading.enumerate():
if t.name == 'MainThread':
main = t
print "Thread B started"
x = 0
while main and main.isAlive():
time.sleep(1)
x = x + 1
print x
將main
存儲在全局范圍內以供所有線程使用是一個好主意,而不必在每個子線程的初始化時查找主線程。 但這可以在你的例子中完成工作。
main
將通過迭代所有線程( .enumerate()
)然后將名為“MainThread”的線程放入main
,然后調用main.isAlive()
來檢查它是否仍在運行,從而處理主線程。 如果main
為None
或False
或者.isAlive()
返回False
,則表示該線程不存在或死亡,關閉子線程:)
你不能“切換”線程。 因此,一旦完成主線程,就必須等待其他線程使用方法join
終止。 但請注意:
join
方法是不是可中斷的KeyboardInterrupt
,您需要通過指定超時和循環檢測用戶中斷。 sys.stdout
(打印時使用) 我在一個名為ThreadHandler
的類中收集了這些方面,請看一下:
import threading, time
def printCount(lock, stop):
with lock:
print "Thread B started"
x = 0
while not stop.is_set():
time.sleep(1)
x = x + 1
with lock:
print x
class ThreadHandler():
STEP = 0.2
def __init__(self, target):
self.lock = threading.Lock()
self.stop = threading.Event()
args = (self.lock, self.stop)
self.thread = threading.Thread(target=target, args=args)
def start(self):
self.thread.start()
def join(self):
while self.thread.is_alive():
try:
self.thread.join(self.STEP)
except KeyboardInterrupt:
self.stop.set()
## User Code ##
print "begin!"
handler = ThreadHandler(target=printCount)
handler.start()
with handler.lock:
print "woop!"
handler.join()
你無法像這樣切換線程。 它不像那樣工作。
但是,您可以使用帶有全局標志ALIVE
信號:
import threading, time, signal
ALIVE = True
def handle_sigint(signum, frame):
global ALIVE
ALIVE = False
signal.signal(signal.SIGINT, handle_sigint)
def printCount():
print "Thread B started"
x = 0
while ALIVE: # <--- note the change
time.sleep(1)
x = x + 1
print x
## User Code ##
print "begin!"
threadB = threading.Thread(target=printCount)
threadB.start()
print "woop!"
signal.pause() # <--- wait for signals
現在按CTRL + C后它會正常退出。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.