ホームページ >バックエンド開発 >Python チュートリアル >Python マルチスレッドにおけるブロッキング (結合) とロック (Lock) の使用に関する誤解の分析
この記事は主にすべての人に向けて詳しく説明します この記事では、Python マルチスレッドにおける join と lock のブロックに関する誤解について紹介します。興味のある方は、
メインスレッドのブロックの間違った使い方について
join
Thread.join ( ) この機能は、メインスレッドをブロックすることです。つまり、子スレッドが返さない場合、メインスレッドは子スレッドが戻るのを待ってから実行を継続します。
join はループ内で start と組み合わせて使用することはできません。以下はエラー コードです。コードは 5 つのスレッドを作成し、ループを使用してスレッドをアクティブ化し、アクティブ化後にメイン スレッドをブロックします。
1.メインスレッドは start 関数を通じてスレッド 1 を起動し、スレッド 1 は計算を実行します。
2. start 関数はメインスレッドをブロックしないため、スレッド 1 が演算を実行している間、メインスレッドは join 関数を下向きに実行します。 join の実行後、メインスレッドはスレッド 1 によってブロックされます。スレッド 1 が結果を返す前に、メインスレッドは次のサイクルを実行できません。4. スレッド 1 の計算が完了したら、メインスレッドのブロックを解除します。メインスレッドは次のサイクルに入り、スレッド 2 をアクティブにし、スレッド 2 によってブロックされます...
このようにして、同時であるはずだった 5 つのスレッドがここで順次キューになり、効率が向上していることがわかります。
join
の正しい使用法は、
start
join
関数をそれぞれ処理するために2つのループを使用します。threads = [Thread() for i in range(5)] for thread in threads: thread.start() thread.join()
time。 .sleep はデバッグ用の join を置き換えます 以前、いくつかのプロジェクトで、join の代わりに time.sleep を使用してメインスレッドを手動でブロックするそのようなコードを見たことがあります。終了できませんでした。
threads = [Thread() for i in range(5)] for thread in threads: thread.start() for thread in threads: thread.join()
スレッドロック(threading.Lock)について
シングルコアCPU+PILにはまだロックが必要ですか?
非アトミック操作
count = count + 1理論的には、スレッドアンセーフです。
3 つのスレッドを使用して上記の操作を同時に実行し、グローバル変数 count の値を変更し、プログラムの実行結果を確認します。結果が正しい場合は、スレッドが存在しないことを意味します。競合します。次のコードを使用してテストします
for thread in threads: thread.start() while 1: if thread_num == 0: break time.sleep(0.01)
実行結果:
実際、各実行の結果は異なり、間違っています。これは、シングルコア CPU+ であることを証明しています。 PIL は依然としてスレッドの安全性を保証できないため、ロックする必要があります。
ロック後の正しいコード:
# -*- coding: utf-8 -*- import threading import time count = 0 class Counter(threading.Thread): def __init__(self, name): self.thread_name = name super(Counter, self).__init__(name=name) def run(self): global count for i in xrange(100000): count = count + 1 counters = [Counter('thread:%s' % i) for i in range(5)] for counter in counters: counter.start() time.sleep(5) print 'count=%s' % count
結果:count=500000 ロックのグローバルな性質に注意してください
これは単純な Python 構文の問題ですが、ロジックが複雑な場合に発生します。無視される可能性があります。
ロックが複数のサブスレッドで共有されていることを確認してください。つまり、Thread のサブクラス内にロックを作成しないでください。以下はエラーコードです
# -*- coding: utf-8 -*- import threading import time count = 0 lock = threading.Lock() class Counter(threading.Thread): def __init__(self, name): self.thread_name = name self.lock = threading.Lock() super(Counter, self).__init__(name=name) def run(self): global count global lock for i in xrange(100000): lock.acquire() count = count + 1 lock.release() counters = [Counter('thread:%s' % i) for i in range(5)] for counter in counters: counter.start() time.sleep(5) print 'count=%s' % count
Pythonスレッドの同期ロックの詳細な説明
以上がPython マルチスレッドにおけるブロッキング (結合) とロック (Lock) の使用に関する誤解の分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。