你如何讓兩條路由控制python中的守護執行緒
燒瓶后端檔案
from flask import Flask
from time import time,sleep
from threading import Thread
app = Flask(__name__)
def intro():
while True:
sleep(3)
print (f" Current time : {time()}")
@app.route('/startbot')
def start_bot():
global bot_thread
bot_thread = Thread(target=intro, daemon=True)
bot_thread.start()
return "bot started "
@app.route('/stopbot')
def stop_bot():
bot_thread.join()
return
if __name__ == "__main__":
app.run()
當試圖殺死執行緒時,終端中的 curl 請求不會回傳到控制臺,并且執行緒會繼續將資料列印到終端
我的想法是我將宣告包含對 bot_thread 的參考的變數并使用路由來控制它
來測驗我使用curl http://localhost:port/startbot的curl http://localhost:port/stopbot
我可以很好地啟動機器人但是當我試圖殺死它時,我得到以下資訊
NameError: name 'bot_thread' is not defined
非常感謝任何幫助和注意事項
考慮到在殺死執行緒后,用戶可以創建一個新執行緒并且也能夠殺死它
uj5u.com熱心網友回復:
這是一個最小的可重現示例:
from threading import Thread
def intro():
print("hello")
global bot_thread
def start_bot():
bot_thread = Thread(target=intro, daemon=True)
return
def stop_bot():
if bot_thread:
bot_thread.join()
if __name__ == "__main__":
import time
start_bot() # simulating a request on it
time.sleep(1) # some time passes ...
stop_bot() # simulating a request on it
Traceback (most recent call last):
File "/home/stack_overflow/so71056246.py", line 25, in <module>
stop_bot() # simulating a request on it
File "/home/stack_overflow/so71056246.py", line 17, in stop_bot
if bot_thread:
NameError: name 'bot_thread' is not defined
我的IDE使錯誤在視覺上對我來說很清楚:bot_thread未使用,因為它是區域變數,而不是區域變數global,盡管它們具有相同的名稱。這對 Python 程式員來說是一個陷阱,例如看這個問題或這個問題。
所以 :
def start_bot():
global bot_thread
bot_thread = Thread(target=intro, daemon=True)
return
但
Traceback (most recent call last):
File "/home/stack_overflow/so71056246.py", line 26, in <module>
stop_bot() # simulating a request on it
File "/home/stack_overflow/so71056246.py", line 19, in stop_bot
bot_thread.join()
File "/usr/lib/python3.9/threading.py", line 1048, in join
raise RuntimeError("cannot join thread before it is started")
RuntimeError: cannot join thread before it is started
因此 :
def start_bot():
global bot_thread
bot_thread = Thread(target=intro, daemon=True)
bot_thread.start()
return
最后給出:
hello
編輯
當試圖殺死執行緒時,終端中的 curl 請求不會回傳到控制臺,并且執行緒會繼續將資料列印到終端
@prometheus the bot_thread runs the intro function. Because it contains an infinite loop (while True) it will never reach the end of the function (implicit return) so the thread is never considered as finished. Because of that, when the main thread tries to join (wait until the thread finishes, then get the result), it waits endlessly because the bot thread is stuck in the loop.
So you have to make it possible to exit the while loop. For example (like in the example I linked in a comment), by using another global variable, a flag, that gets set in the main thread (route stop_bot) and that is checked in the intro loop. Like so :
from time import time, sleep
from threading import Thread
def intro():
global the_bot_should_continue_running
while the_bot_should_continue_running:
print(time())
sleep(1)
global bot_thread
global the_bot_should_continue_running
def start_bot():
global bot_thread, the_bot_should_continue_running
bot_thread = Thread(target=intro, daemon=True)
the_bot_should_continue_running = True # before the `start` !
bot_thread.start()
return
def stop_bot():
if bot_thread:
global the_bot_should_continue_running
the_bot_should_continue_running = False
bot_thread.join()
if __name__ == "__main__":
start_bot() # simulating a request on it
sleep(5.5) # some time passes ...
stop_bot() # simulating a request on it
prints 6 times then exits.
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/424587.html
