2016-03-31 11 views
0

Da CPython über die GIL verfügt, dürfen keine Threads Python-Code zur gleichen Zeit ausführen, daher scheint es Threadsicherheit innerhalb eines bestimmten Prozesses zu geben.CPython und Threading-Modul Lock()

Was ist der Zweck des Python-Threading-Moduls Lock()? Welche Synchronisationsprobleme können in CPython noch auftreten, die Lock() hilft, obwohl keine Threads zur gleichen Zeit ausgeführt werden können?

Antwort

1

Die GIL stellt nur sicher, dass immer nur ein Thread ausgeführt werden kann. Es ist immer noch möglich, dass ein Thread zwischen Anweisungen unterbrochen wird und ein anderer Thread eine Chance hat, ausgeführt zu werden. Wenn zwei Threads auf eine freigegebene Ressource zugreifen, muss der Zugriff daher durch eine Sperre geschützt werden.

Lassen Sie sich dieses Beispiel nehmen:

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() 

Obwohl es wie der if Zustand aussieht, kann unmöglich immer wahr sein, ist es eine gute Chance, dass Sie die Zeile gedruckt sehen werden. Wie kann das sein?

Wenn man sich die zerlegten Bytecode von func suchen (durch dis.dis(func) vom dis Modul aufruft), das ist, was Sie bekommen:

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 

Die entsprechenden Anweisungen sind 25 und 28. Wenn der Faden bekommt unterbrochen zwischen diesen beiden Anweisungen, ein anderes Therad kann die globale Variable i ändern und die gespeicherten Werte werden unterschiedlich sein.

+0

Wirklich nette Antwort! Vielen Dank – dylan7