2014-11-11 7 views
7

파이썬 스레드는 바이트 코드를 한 번에 하나씩 만 실행할 수 있다는 것을 알고 있습니다. 따라서 threading 라이브러리가 잠금을 제공하는 이유는 무엇입니까? 한 번에 하나의 스레드 만 실행 중이면 경쟁 조건이 발생할 수 없다고 가정합니다.GIL을 준수하는 경우 Python이 잠금 메커니즘을 제공하는 이유는 무엇입니까?

라이브러리는 잠금, 조건 및 세마포어를 제공합니다. 실행을 동기화하는 유일한 목적입니까? 업데이트

: 나는 작은 실험을 수행

: 결과가 반환 1. 에 의해 기본적으로

from threading import Thread 
from multiprocessing import Process 

num = 0 

def f(): 
    global num 
    num += 1 

def thread(func): 
    # return Process(target=func) 
    return Thread(target=func) 


if __name__ == '__main__': 
    t_list = [] 
    for i in xrange(1, 100000): 
     t = thread(f) 
     t.start() 
     t_list.append(t) 

    for t in t_list: 
     t.join() 

    print num 

내가 100,000 스레드를 시작 증가해야했다 99993.

A) GIL 동기화 및 피싱 경쟁 조건이있는 경우 어떻게 결과가 99999가 될 수 있습니까? b) 100k OS 스레드를 시작할 수 있습니까?

업데이트 2, 답변보고 후 다음 GIL 정말 원자 증가와 같은 간단한 작업을 수행 할 수있는 방법, 거기있는의 목적은 무엇을 제공하지 않는 경우

를? 그것은 불쾌한 동시성 문제 때문에 도움이되지 않습니다. C- 확장에 대한 사용 사례를 들었는데 누군가가 이것을 증명할 수 있습니까?

+1

GIL은 코드 작성보다는 동시성 문제로부터 Python 인터프리터 자체를 보호합니다. 이것은 실제로 CPython의 구현 세부 사항입니다. 여러분의 코드에서 동작을 의존해서는 안되며, 곧 없어지지는 않을 것입니다. – dano

답변

8

GIL은 바이트 코드 작업을 동기화합니다. 한 번에 1 바이트 코드 만 실행할 수 있습니다. 그러나 하나 이상의 바이트 코드가 필요한 작업이 있으면 바이트 코드간에 스레드를 전환 할 수 있습니다. 조작이 원 자성이 필요하면 GIL 이상에서 동기화가 필요합니다. 여기

>>> def f(): 
... global num 
... num += 1 
... 
>>> dis.dis(f) 
    3   0 LOAD_GLOBAL    0 (num) 
       3 LOAD_CONST    1 (1) 
       6 INPLACE_ADD 
       7 STORE_GLOBAL    0 (num) 
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE 

그것이 num += 1을 구현하기 위해 네 개의 바이트 코드에 나섭니다 : 예를 들어

는, 정수를 증가하는 것은 하나의 바이트 코드가 아닙니다. GIL은 x가 원자 적으로 증가하도록 보장하지 않습니다. 실험 결과 LOAD_GLOBAL과 STORE_GLOBAL 사이에서 스레드가 전환되었으므로 업데이트가 손실되었습니다.

GIL의 목적은 파이썬 객체의 참조 카운트가 원자 적으로 증가 및 감소되도록하는 것입니다. 자신의 데이터 구조에 도움이되는 것은 아닙니다.

3

파이썬의 네이티브 스레드는 바이트 코드 수준에서 작동합니다. 즉, 각 바이트 코드 후에 (실제로, 바이트 코드의 수는 구성 가능하다고 생각합니다), 스레드는 다른 스레드로 제어권을 양보 할 수 있습니다.

단일 바이트 코드가 아닌 공유 리소스의 모든 작업에는 잠금이 필요합니다. 그리고 특정 연산이 CPython의 특정 버전에서 모든 인터프리터 버전에 해당하지 않는 단일 바이트 코드 일지라도 어쨌든 잠금을 사용하는 것이 좋습니다.

하드웨어 수준이 아닌 VM 수준을 제외하고는 잠금이 필요한 것과 같은 이유가 있습니다.