CPythonにはGILがあるため、スレッドは同時にPythonコードを実行することはできません。したがって、特定のプロセス内でスレッドの安全性があるようです。CPythonとスレッドモジュールLock()
PythonスレッドモジュールLock()
の目的は何ですか?どのスレッドも同時に実行することはできないのに、Lock()
が助けているCPythonではどのような同期の問題が依然として発生する可能性がありますか?
CPythonにはGILがあるため、スレッドは同時にPythonコードを実行することはできません。したがって、特定のプロセス内でスレッドの安全性があるようです。CPythonとスレッドモジュールLock()
PythonスレッドモジュールLock()
の目的は何ですか?どのスレッドも同時に実行することはできないのに、Lock()
が助けているCPythonではどのような同期の問題が依然として発生する可能性がありますか?
GILは、一度に実行できるスレッドが1つだけであることを確認します。命令間でスレッドが中断され、別のスレッドが実行される可能性があります。したがって、2つのスレッドが共有リソースにアクセスする場合、アクセスはロックで保護する必要があります。
はのは、この例を見てみましょう:from threading import Thread
i = 0
def func():
global i
while i < 1000000:
i += 1
if i != i:
print("i was modified")
for _ in range(10):
Thread(target=func).start()
それはおそらく今まで本当のことはできませんif
状態のように見えますが、あなたが印刷された行が表示されます良いチャンスがあります。どのようにすることができますか?
あなたは(dis
モジュールからdis.dis(func)
を呼び出すことによって)func
の分解バイトコードを見れば、これはあなたが買ってあげるものです:
7 0 SETUP_LOOP 51 (to 54)
>> 3 LOAD_GLOBAL 0 (i)
6 LOAD_CONST 1 (1000000)
9 COMPARE_OP 0 (<)
12 POP_JUMP_IF_FALSE 53
8 15 LOAD_GLOBAL 0 (i)
18 LOAD_CONST 2 (1)
21 INPLACE_ADD
22 STORE_GLOBAL 0 (i)
9 25 LOAD_GLOBAL 0 (i)
28 LOAD_GLOBAL 0 (i)
31 COMPARE_OP 3 (!=)
34 POP_JUMP_IF_FALSE 3
10 37 LOAD_GLOBAL 1 (print)
40 LOAD_CONST 3 ('i was modified')
43 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
46 POP_TOP
47 JUMP_ABSOLUTE 3
50 JUMP_ABSOLUTE 3
>> 53 POP_BLOCK
>> 54 LOAD_CONST 0 (None)
57 RETURN_VALUE
スレッドが取得する場合は、関連する命令は25と28ですこれらの2つの命令の間で中断された場合、もう1つのブラッドはグローバル変数i
を変更することができ、格納された値は異なります。
本当に素敵な答えです!ありがとうございました – dylan7