今日の記事では、PythonでDaemon Threadsを使うことについて見ていきます。
デーモンスレッド
Daemon Thread は、バックグラウンドで独立して実行できるスレッドの一種です。
この種のスレッドは、メインスレッドとは独立して実行されます。
つまり、ノンブロッキングスレッドと呼ばれるものです。
Pythonでデーモンスレッドが必要になるのはどんなときでしょうか?
例えば、ログファイルを読もうとする長時間実行するタスクが必要だとします。
このタスクは、ログにエラーメッセージを検出したときに、ユーザーに警告する必要があります。
このタスクにデーモンスレッドを割り当てれば、メインプログラムが通常の仕事をしている間、ログファイルを監視し続けることができます!
デーモンスレッドの最も優れた点は、メインプログラムが終了すると自動的に実行を停止することです!
短いタスクが必要な場合、デーモンスレッドは、それが戻った後、実行を停止します。
しかし、この性質上、デーモンスレッドは長時間実行されるバックグラウンドタスクに広く使用されます。
では、Pythonでどのように使用できるかを示す例を見てみましょう!
Python でデーモンスレッドを使う – 実践的な実装例
Python のこれらの例では、標準ライブラリの一部である Python の threading モジュールを使用します。
import threading |
デーモンスレッドの威力を説明するために、まずAとBの2つのスレッドを作成しましょう。
スレッドAは短い計算を実行し、スレッドBは共有リソースを監視しようとします。
このリソースが True に設定されている場合、スレッド B はその状態についてユーザーに警告するようにします。
import threading
import time
# Set the resource to False initiallyshared_resource = False
# A lock for the shared resource
lock = threading.Lock()
def perform_computation():
# Thread A will call this function and manipulate the resource
print(f'Thread {threading.currentThread().name} - performing some computation....')
shared_resource = True
print(f'Thread {threading.currentThread().name} - set shared_resource to True!')
print(f'Thread {threading.currentThread().name} - Finished!')
time.sleep(1)
def monitor_resource():
# Thread B will monitor the shared resource
while shared_resource == False:
time.sleep(1)
print(f'Thread {threading.currentThread().name} - Detected shared_resource = False')
time.sleep(1)
print(f'Thread {threading.currentThread().name} - Finished!')
if __name__ == '__main__':
a = threading.Thread(target=perform_computation, name='A')
b = threading.Thread(target=monitor_resource, name='B')
# Now start both threads
a.start()
b.start()
|
ここでは、スレッド A は shared_resource を True に設定し、スレッド B はこのリソースが True になるのを待つことになる。
結果は以下の通りです。
Thread A - performing some computation....
Thread A - set shared_resource to True!
Thread A - Finished!
Thread B - Detected shared_resource = False
Thread B - Finished!
|
どちらのスレッドも通常のスレッドであることに注意してください。
ここで、スレッドBをデーモンスレッドにしてみましょう。
何が起こるか見てみましょう。
そのためには、threading.Thread(daemon=True)メソッドでパラメータとして設定すればいいのです。
import threading
import time
shared_resource = False # Set the resource to False initially
lock = threading.Lock() # A lock for the shared resource
def perform_computation():
# Thread A will call this function and manipulate the resource
print(f'Thread {threading.currentThread().name} - performing some computation....')
shared_resource = True
print(f'Thread {threading.currentThread().name} - set shared_resource to True!')
print(f'Thread {threading.currentThread().name} - Finished!')
time.sleep(1)
def monitor_resource():
# Thread B will monitor the shared resource
while shared_resource == False:
time.sleep(1)
print(f'Daemon Thread {threading.currentThread().name} - Detected shared_resource = False')
time.sleep(1)
print(f'Daemon Thread {threading.currentThread().name} - Finished!')
if __name__ == '__main__':
a = threading.Thread(target=perform_computation, name='A')
b = threading.Thread(target=monitor_resource, name='B', daemon=True) # Make thread B as a daemon thread
# Now start both threads
a.start()
b.start()
|
結果は以下の通りです。
Thread A - performing some computation....
Thread A - set shared_resource to True!
Thread A - Finished!
Daemon Thread B - Detected shared_resource = False
|
ここで、デーモンスレッドは終了しないことに注意してください。
これは、メインスレッドによって自動的に kill されるからです。
デーモンスレッドのノンブロッキングの性質は、多くのPythonアプリケーションで非常に有用です。
まとめ
この記事では、Pythonアプリケーションでデーモンスレッドを使用する方法について学びました。