スレッドを使用するときは、主に共有データの同期に関するいくつかのことをよく理解する必要があります。あなたは、ロック、rlocks、セマフォーなどを使用する必要があります。非常にシンプルな共有データでも書いていますか?Pythonのアトミックアクセス(スレッドに関連)
たとえば、グローバルリソースを共有する2つのスレッド、つまり単純なブール変数があります。
import threading
import random
import time
active = True
class T1(threading.Thread):
def run(self):
while active:
print("Hello") # do some work
time.sleep(0.1)
class T2(threading.Thread):
def run(self):
global active
while random.random() > 0.05:
time.sleep(1)
active = False
t1, t2 = T1(), T2()
t1.start()
t2.start()
t1.join()
t2.join()
動作しているようですが、pythonが動作することを保証していますか?はいの場合は、正確にどのような理由で動作しますか?
私には3つの答えがあります。
- ブール変数のアクセスは常にアトミック(別のスレッドで中断できない)なので機能します。この場合、Pythonはアトミック操作として何を保証しますか?整数、リスト、辞書のアトミックなアクセスですか?
- Pythonは毎回このコードが動作することを保証しません。解決策は、両方のスレッドでアクティブ変数にアクセスするためにロックを使用することです。
- これは、1つのスレッドだけが変数を書き込むために機能します。もう一方のスレッドはそれを読み込みます。
ここでは、別のコードである:今
import threading
import random
import time
numbers = [3]
class T1(threading.Thread):
def run(self):
while sum(numbers) % 3 == 0:
print("Hello") # do some work
time.sleep(0.1)
class T2(threading.Thread):
def run(self):
global active
while random.random() > 0.2:
numbers.extend([1, 2])
time.sleep(1)
numbers.append(4)
t1, t2 = T1(), T2()
t1.start()
t2.start()
t1.join()
t2.join()
がを単一と "複合"命令numbers.extendできた([1、2])T1スレッドによって中断さ?この場合、1が追加された直後で2が追加される直前に、T2はT2の前に意図せず停止する可能性があります。
2つのスレッドからの行は任意にインターリーブされるかもしれませんが、あなたのコードは本当にアトミックな一連のアクションに依存しません。あなたのコードは原子的に実行されている単一行にのみ依存していますが、CPythonでは常に信頼できるはずです – stevenjackson121
「同時にコード」と「単一の変数に」とはどういう意味ですか? Pythonでは、*単一*命令は変数や複雑なオブジェクトに対して多くのことを行うことができます。 Pythonは単一の命令(2つのオブジェクト間のコピーやループや関数呼び出しなど)を他のスレッドで中断することはできませんか?どのスレッドが別のスレッドを中断できるかを私はどのように理解できますか? – pozzugno
*スレッドが任意の2つの命令間で別のスレッドを中断できるとは思いますが、わかりません。式 'i = 2 + 3 * 10 + 17'は多くの別々の命令を持っていますが、完全な右側が評価され、最後に割り当てi = 49が発生します。 'i'の値が以前に' 10'だった場合、 'i'の値を繰り返しチェックしている別のスレッドは' i == 10'または 'i == 49'しか見ません。「2 + 3 * 10 + 17」の計算中に「i」は決してない – stevenjackson121