2016-08-29 17 views
2

내가 이해 한 바로는 Global Interpreter Lock은 하나의 스레드 만 인터프리터에 액세스하고 바이트 코드를 실행할 수 있도록 허용합니다. 그렇다면 주어진 시간에 오직 하나의 쓰레드 만 인터프리터와 메모리를 사용할 것입니다.CPython에서 스레드 안전성에 대해 걱정해야하는 이유는 무엇입니까?

그렇기 때문에 두 스레드가 동시에 인터프리터의 메모리에 액세스 할 수 없기 때문에 경합 사례가 발생할 가능성을 배제하는 것이 합리적이라고 생각하지만 데이터 구조가 "스레드 안전"인지에 대한 경고를 볼 수 있습니다. . 파이썬 인터프리터 (cython과 같은)의 모든 구현을 커버 할 수있는 가능성이 있습니다. 파이썬 인터프리터는 GIL을 끌 수 있고 진정한 멀티 스레딩을 허용 할 수 있습니다.

GIL을 사용할 수없는 인터프리터 환경에서 스레드 안전성의 중요성을 알고 있습니다. 그러나 CPython의 경우 다중 스레드 파이썬 코드를 작성할 때 스레드 안전성을 장려하는 이유는 무엇입니까? CPython 환경에서 발생할 수있는 더 나쁜 점은 무엇입니까?

답변

6

데이터 구조에 대한 액세스가이 아닌 이기 때문에 경쟁 조건이 계속 발생할 수 있습니다.

if key not in dictionary: 
    # calculate new value 
    value = elaborate_calculation() 
    dictionary[key] = value 

not in 테스트가 진정한 리턴 한 후 스레드는 언제든지 전환 할 수 있고, 다른 :

는 다음 키를 추가 할 무언가를 당신이 사전에 존재하는 중요한 테스트 말 스레드 또한 키가 없다는 결론에 도달하게됩니다. 이제 두 개의 쓰레드가 계산을하고 있으며 어느 것이 승리 할 지 모릅니다.

GIL은 파이썬의 내부 인터프리터 상태을 보호합니다. 그렇다고해서 파이썬 코드 자체가 사용하는 데이터 구조가 잠겨서 보호되지 않는다는 의미는 아닙니다.

0

중요 사항 : 파이썬의 다중 처리 모듈은 GIL에도 불구하고 동일한 변수에 대한 액세스가 여러 프로세스에서 동시에 발생할 수 있다는 점에서 어느 정도의 동기가 있습니다.

이렇게하면 데이터가 손상되거나 제어 흐름이 중단되어 스레드 안전이 왜 좋은지 알 수 있습니다.

하나의 인터리터 만있을지라도 왜 공유 메모리의 동일한 부분에 동시 적으로 액세스하는 두 개의 미리 정의 된 코드 조각을 멈추는 것도 없습니다 (적어도 알 수있는 한). 일을 할 때 말 :

import multiprocessing 
def my_func(): 
    print("hello world") 
my_process=multiprocessing.Process (target=my_func, args=(,)) 
my_process.start() 
my_process.join() 

나의 이해는 그것이 my_func (이 경우) interprit하는 데 걸리는 시간은 새로운 프로세스를 생성하는 데 걸리는 오버 헤드에 묻혔다는 것이다.

데이터를 복사하기 위해 임시로 생성되는 작업자 스레드가 있기 때문에 "프로세스"라는 용어가 더 적합합니다. 따라서 데이터 핸드 쉐이킹이 수행되므로 실제로는 상당히 다른 프로세스입니다 (의도 된 말장난) 전통적인 스레드의 산란보다.

이 정보가 도움이되기를 바랍니다.