簡體   English   中英

Python 線程自調用線程意外行為

[英]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 的絕對值不成比例地增長。 我做了兩個觀察: 觀察1、1個task1線程和5個task2線程 觀察 2、3 個 task1 線程和 7 個 task 2 線程

同樣,我希望 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM