簡體   English   中英

Python:了解線程和退出線程

[英]Python: Understanding Threading and Exiting Threads

這是我第一次使用線程。 我想我了解基本知識,但是我不確定退出線程如何工作。

考慮代碼:

class myThread (threading.Thread):
  def __init__(self, threadID, name, counter):
    threading.Thread.__init__(self)
    self.threadID = threadID
    self.name = name
    self.counter = counter
    self.stoprequest=threading.Event()
  def run(self):
    while not self.stoprequest.isSet():
      print("Starting " + self.name)
      print_time(self.name,self.counter)
      print("Exiting " + self.name)

  def join(self, timeout=None):
    self.stoprequest.set()
    super(myThread,self).join(timeout)

def print_time(threadName, delay):
  time.sleep(delay)
  print("%s: %s" % (threadName, time.ctime(time.time())))


thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# Start new Threads
thread1.start()
thread2.start()

print("Exiting Main Thread")

根據我對線程的了解,它們永遠都不會結束,直到調用join()為止,但是每個線程的while循環內只有1個循環之后,代碼才會退出。 輸出:

Starting Thread-1
Starting Thread-2
Exiting Main Thread
Thread-1: Wed Mar 13 09:13:32 2019
Exiting Thread-1
Thread-2: Wed Mar 13 09:13:33 2019
Exiting Thread-2

注意:我不是親自編寫此代碼,而是在網上找到了代碼並對其進行了調整,以更好地理解線程。

所以我的問題是:

  1. 在上面的代碼中,為什么當從未調用join()時,線程僅執行while循環的一個周期? 我希望線程永遠不會結束。
  2. 在用戶決定退出線程程序之前,我將如何使其運行? 我的主要目標是讓腳本掃描並分析文件,直到用戶告訴它退出為止。

謝謝!

UPDATE

原始答案是錯誤的,因為它錯過了@ranjith在評論部分中建議的重要觀點。

如果刪除myThread定義中的join函數,您將發現該程序不會退出,如@ranjith所述。 原因是因為當主線程存在時,它會自動在其所有非守護進程線程上調用join ,如源代碼所示 如果您從未為myThread類實現join ,則調用join將立即返回而不會終止子線程。

在您的情況下, join是正確實現的,它將self.stoprequest事件設置為true,表示兩個子線程停止。 因此,當主線程退出時,兩個子線程也退出。

最后,請注意正確實現join與不實現join但將daemon設置為true之間的區別,盡管它們的行為類似(子線程在存在主線程時停止)。 如果將daemon設置為true,則在主線程退出時子線程將不會等待直到停止 (請參閱本節中的“注意”),而實現join則相反。


下面的原始答案

這是因為您的python程序退出了,因此所有子線程都被隱式殺死。 您需要保持程序運行,才能看到兩個子線程繼續打印內容。

例如,用下面的內容替換打印語句:

while True:
    print_time('Main', 3)

根據我對線程的了解,它們永遠都不應結束,直到調用join()

這不是真的。 這完全取決於您如何實現在線程中運行的任務。 通過重寫Thread類的run方法或將您的任務(可調用的函數)作為目標(將在Thread的run方法中調用)作為目標。 當任務終止或出現某種異常時,線程結束。 Thread上的join方法實際上要等到線程終止。 您還可以提供超時(僅等待特定時間)

1.在上面的代碼中,為什么當從未調用join()時,線程僅執行while循環的一個周期? 我希望線程永遠不會結束。

您怎么知道它執行一個周期? 使用您的代碼,我的任務將永遠運行我的輸出,

Starting Thread-2
Thread-1: Wed Mar 13 12:03:42 2019
Exiting Thread-1
Starting Thread-1
Thread-1: Wed Mar 13 12:03:43 2019
Exiting Thread-1
Starting Thread-1
Thread-2: Wed Mar 13 12:03:44 2019
Exiting Thread-2
Starting Thread-2
Thread-1: Wed Mar 13 12:03:44 2019
Exiting Thread-1
Starting Thread-1
Thread-1: Wed Mar 13 12:03:46 2019
Exiting Thread-1
Starting Thread-1
#and goes on

在用戶決定退出線程程序之前,我將如何使其運行? 我的主要目標是讓腳本掃描並分析文件,直到用戶告訴它退出為止。

取決於您如何編寫目標/可運行方法。 您可以在那里運行永久的邏輯。 將線程視為正在從當前(主)程序中分離出來的一項工作。 您應該將您的任務設計為原子且簡單!

在這里閱讀更多

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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