記事ディレクトリ
シリーズ特集Python
クローラーは遅いですか? 同時プログラミングについて学ぶ
デーモンスレッド
マルチスレッドではPython
、メインスレッドのコードの実行が終了した後、実行が完了していない他のサブスレッドがある場合、メインスレッドはサブスレッドの実行が完了するまで待ってから終了しますPython
。例を見てみましょう。
import threading
import time
# 非守护线程
def normal_thread():
for i in range(10000):
time.sleep(1)
print(f'normal thread {
i}')
print(threading.current_thread().name, '线程开始')
thread1 = threading.Thread(target=normal_thread)
thread1.start()
print(threading.current_thread().name, '线程结束')
MainThread
上記の結果から、メインスレッド ( ) は終了しても、サブスレッドはまだ実行されており、サブスレッドの実行後、プログラム全体が実際に終了することがわかります。その後、メイン スレッドの終了と同時に他の未完了のスレッドを終了したい場合は、そのスレッドを デーモン スレッドとして設定することができます。プログラム内でデーモンスレッドのみが実行中で、メイン プログラムも終了する場合、Python
プログラムは正常に終了できます。threading
このモジュールは、デーモン スレッドを設定する 2 つの方法を提供します。
threading.Thread(target=daemon_thread、daemon=True)
thread.setDaemon(True)
import threading
import time
# 守护线程(强制等待1s)
def daemon_thread():
for i in range(5):
time.sleep(1)
print(f'daemon thread {
i}')
# 非守护线程(无强制等待)
def normal_thread():
for i in range(5):
print(f'normal thread {
i}')
print(threading.current_thread().name, '线程开始')
thread1 = threading.Thread(target=daemon_thread, daemon=True)
thread2 = threading.Thread(target=normal_thread)
thread1.start()
# thread1.setDaemon(True)
thread2.start()
print(threading.current_thread().name, '线程结束')
上記のthread1
セットはデーモン スレッドであり、プログラムは非デーモン スレッドとメイン スレッド( MainThread
) の実行直後に終了するため、daemon_thread()
の出力ステートメントを実行する時間がありません。図の出力では、メインスレッドの終了からデーモンスレッドの強制停止までの処理に時間がかかるため、スレッド終了後も関数の内容MainThread
が出力されていることがわかります。normal_thread()
デーモンスレッドの継承
daemon
子スレッドは現在のスレッドの属性を継承し、メインスレッドはデフォルトで非デーモンスレッドであるため、メインスレッド内に新しく作成されるスレッドもデフォルトでは非デーモンスレッドですが、デーモンスレッド内に新しいスレッドが作成されると、現在のスレッドの属性を継承しdaemon
、子スレッドもデーモンスレッドになります。
join() のブロック
マルチスレッド クローラーでは、通常、異なるページの情報が複数のスレッドを同時に巡回され、統合された方法で分析および処理され、統計が保存されるため、すべてのサブスレッドの実行が完了するのを待ってから次の処理を続行する必要があり、メソッドを使用する必要がありますjoin()
。
join()
このメソッドの機能は、他のスレッド (未起動のスレッドとメイン スレッド) をブロック (一時停止) し、呼び出されたスレッドの実行が終了するのを待ってから、他のスレッドを起動して実行することです。例を見てみましょう。
import threading
import time
def block(second):
print(threading.current_thread().name, '线程正在运行')
time.sleep(second)
print(threading.current_thread().name, '线程结束')
print(threading.current_thread().name, '线程正在运行')
thread1 = threading.Thread(target=block, name=f'thread test 1', args=[3])
thread2 = threading.Thread(target=block, name=f'thread test 2', args=[1])
thread1.start()
thread1.join()
thread2.start()
print(threading.current_thread().name, '线程结束')
上記はthread1
使用のみです。使用される位置join()
に注意してください。開始前、実行後、メインスレッドが一時停止された後、スレッドの実行が完了した後にのみ実行されます。メインスレッドはデーモンスレッドではないため、メインスレッド ( ) が実行されると実行を継続します。join()
thread2.start()
thread2
thread1
thread2
thread2
MainThread
thread2
これを見て何か質問はありますか?上記のコードの実行処理を行うと、プログラム全体が完全にシングルスレッドプログラムになってしまいますが、これは のjoin()
不適切な使用が原因です。上記のコードを少し変更してみましょう。
import threading
import time
def block(second):
print(threading.current_thread().name, '线程正在运行')
time.sleep(second)
print(threading.current_thread().name, '线程结束')
print(threading.current_thread().name, '线程正在运行')
thread1 = threading.Thread(target=block, name=f'thread test 1', args=[3])
thread2 = threading.Thread(target=block, name=f'thread test 2', args=[1])
thread1.start()
thread2.start()
thread1.join()
print(threading.current_thread().name, '线程结束')
これでプログラムは完全にマルチスレッド化され、join()
このときこのメソッドを使用すると、メインスレッドのみが一時停止され、thread1
実行完了後にメインスレッドが実行されます。
join()
最後に、メソッドのブロックはオブジェクトに関係なく、デーモン スレッドがメイン スレッドであるかどうかとは関係がないことを説明する必要があります。使用する際に注意が必要なのは、実際にマルチスレッドで動作させたい場合は、すべてのサブスレッドを起動してから呼び出さないとシングルjoin()
スレッドになってしまうということです。
気が向いたらこの記事はここまでです。❤ いいねして行こう!!!❤
始めたばかりの人Python
、これから始めたいPython
人は、WeChat で [Python New Horizons] を検索して、一緒に交流して学ぶことができます。全員が初心者から来ています。単純な疑問が長い間行き詰まっていることもありますが、他の人がいくつか触れた後、突然明らかになることがあります。皆さんが一緒に進歩できることを心から願っています。