[英]Python Threading Self Calling Threads Unexpected Behavior
我正在測試一種並行運行多個任務的方法。 這些任務將在並行線程中運行,我希望這些任務重復執行,直到設置了全局變量。 我首先嘗試使用線程來啟動並行線程,並確保它們能夠正常工作。 到目前為止我所擁有的:
import threading
from IPython.display import clear_output
import time
i = 0
j = 0
def main():
global i
global j
t1 = threading.Thread(name = "task1", target = task1)
t2 = threading.Thread(name = "task2", target = task2)
t1.start()
t2.start()
def task1():
global i
i += 1
time.sleep(10)
t1 = threading.Thread(name = "task1", target = task1)
t1.start()
def task2():
global j
j -= 1
time.sleep(10)
t2 = threading.Thread(name = "task2", target = task2)
t2.start()
tmain = threading.Thread(name = "main", target = main)
tmain.start()
它啟動一個主線程,然后啟動兩個運行 task1 和 task2 的線程。 要監視當前線程以及 i 和 j 的值,我運行:
while(True):
clear_output(wait=True)
for thread in threading.enumerate():
print(thread)
print(i)
print(j)
time.sleep(0.1)
(所有這些都在 Jupyter Notebook 中運行)。
運行上面的腳本,我注意到了一些意想不到的結果。 我希望在任何給定時間,task1 和 task2 最多應該有兩個線程,但是與 task1 相比,我觀察到 task2 的線程要多得多。 這些不是幽靈或完成的線程,因為 i 和 j 的絕對值不成比例地增長。 我做了兩個觀察:
同樣,我希望 task1 和 task 2 的線程數應該是對稱的,並且我還希望 i 和 j 的絕對值應該比它們更成比例地增長。 任何有關如何減輕這種差異或避免此問題的見解將不勝感激。
我在 Jupyter 中運行了你的代碼,沒有遇到你的問題。
<_MainThread(MainThread, started 139735228168000)>
<Thread(Thread-1, started daemon 139735083251456)>
<Heartbeat(Thread-2, started daemon 139735074858752)>
<HistorySavingThread(IPythonHistorySavingThread, started 139735049680640)>
<Thread(task2, started 139734638634752)>
<Thread(task1, started 139734680598272)>
<Thread(task2, started 139735041287936)>
<Thread(task1, started 139734076618496)>
<Thread(task1, started 139735032895232)>
<Thread(task2, started 139734672205568)>
<Thread(task1, started 139734655420160)>
<Thread(task2, started 139734630242048)>
272
-272
但是正如您已經在自己的代碼中看到的那樣,每個任務都有多個實例在運行。 因此,在一項任務“重新開始”之后,它需要一些時間才能殺死自己。
您的 Jupyter 問題的解決方案可能是讓主 function 控制重新啟動已終止任務。 這確保了每個任務始終只有 1 個線程在運行。
import threading
from IPython.display import clear_output
import time
i = 0
j = 0
main_stop = False
def task1():
global i
i += 1
time.sleep(4)
def task2():
global j
j -= 1
time.sleep(4)
def main():
global i
global j
t1 = threading.Thread(name="task1", target=task1)
t2 = threading.Thread(name="task2", target=task2)
t1.start()
t2.start()
while not main_stop:
if not t1.is_alive():
del t1
t1 = threading.Thread(name="task1", target=task1)
t1.start()
if not t2.is_alive():
del t2
t2 = threading.Thread(name="task2", target=task2)
t2.start()
# wait for tasks to complete
while t1.is_alive():
time.sleep(0.1)
while t2.is_alive():
time.sleep(0.1)
tmain = threading.Thread(name="main", target=main)
tmain.start()
run_time = 30 # seconds
end_time = time.time() + run_time
while time.time() < end_time:
clear_output(wait=True)
for thread in threading.enumerate():
print(thread)
print(i)
print(j)
time.sleep(0.1)
main_stop = True
# wait for main to complete
while tmain.is_alive():
time.sleep(0.1)
print('program completed')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.