2016-03-31 10 views
0

CPythonにはGILがあるため、スレッドは同時にPythonコードを実行することはできません。したがって、特定のプロセス内でスレッドの安全性があるようです。CPythonとスレッドモジュールLock()

PythonスレッドモジュールLock()の目的は何ですか?どのスレッドも同時に実行することはできないのに、Lock()が助けているCPythonではどのような同期の問題が依然として発生する可能性がありますか?

答えて

1

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を変更することができ、格納された値は異なります。

+0

本当に素敵な答えです!ありがとうございました – dylan7

関連する問題