스레드는 Python에서 어떻게 작동하며 일반적인 Python- 스레딩 관련 함정은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/31340

  •  09-06-2019
  •  | 
  •  

문제

나는 스레드가 파이썬에서 어떻게 작동하는지에 대해 머리를 감싸려고 노력해 왔는데, 스레드가 어떻게 작동하는지에 대한 좋은 정보를 찾기가 어렵습니다.링크 나 뭔가 빠졌을 수도 있지만, 공식 문서가 주제에 대해 그다지 철저하지 않은 것 같고 좋은 글을 찾지 못한 것 같습니다.

내가 알 수 있듯이 한 번에 하나의 스레드 만 실행할 수 있으며 활성 스레드는 10 개의 명령마다 전환됩니까?

좋은 설명이 어디에 있습니까? 아니면 설명 할 수 있습니까?Python에서 스레드를 사용하는 동안 발생하는 일반적인 문제를 인식하는 것도 매우 좋습니다.

도움이 되었습니까?

해결책

예, GIL (Global Interpreter Lock) 때문에 한 번에 하나의 스레드 만 실행할 수 있습니다. 이에 대한 몇 가지 통찰력이있는 링크는 다음과 같습니다.

다른 팁

Python은 스레딩하기가 상당히 쉬운 언어이지만주의 할 점이 있습니다. 알아야 할 가장 큰 것은 Global Interpreter Lock입니다. 이렇게하면 하나의 스레드 만 인터프리터에 액세스 할 수 있습니다. 이것은 두 가지를 의미합니다. 1) 파이썬에서 lock 문을 거의 사용하지 않는 경우 2) 다중 프로세서 시스템을 이용하려면 별도의 프로세스를 사용해야합니다. 편집 : 또한 GIL을 둘러보고 싶다면 C / C ++에 일부 코드를 넣을 수 있음을 지적해야합니다.

따라서 스레드를 사용하려는 이유를 재고해야합니다. 듀얼 코어 아키텍처를 활용하기 위해 앱을 병렬화하려면 앱을 여러 프로세스로 분할하는 것을 고려해야합니다.

응답 성을 향상 시키려면 스레드 사용을 고려해야합니다. 하지만 다른 대안, 즉 마이크로 스레딩 이 있습니다. 살펴보아야 할 몇 가지 프레임 워크도 있습니다.

다음은 기본 스레딩 샘플입니다.20 개의 스레드를 생성합니다.각 스레드는 스레드 번호를 출력합니다.그것을 실행하고 그들이 인쇄하는 순서를 관찰하십시오. 라코 디스

당신이 암시했듯이 파이썬 스레드는 시간 분할을 통해 구현됩니다.이것이 그들이 "병렬"효과를 얻는 방법입니다.

예제에서 Foo 클래스는 스레드를 확장 한 다음 스레드에서 실행하려는 코드가있는 run 메서드를 구현합니다.스레드를 시작하려면 스레드 개체에서 start()를 호출하면 자동으로 run 메서드가 호출됩니다 ...

물론 이것은 기본에 불과합니다.결국 스레드 동기화 및 메시지 전달을위한 세마포어, 뮤텍스 및 잠금에 대해 배우고 싶을 것입니다.

개별 작업자가 I / O 바운드 작업을 수행하는 경우 Python에서 스레드를 사용합니다.머신의 여러 코어에서 확장하려는 경우 좋은 IPC python 용 프레임 워크를 사용하거나 다른 언어를 선택하세요.

참고 : thread를 언급 할 때마다 명시 적으로 언급하기 전까지는 구체적으로 python의 스레드 를 의미합니다.

당신이 C/C++ 배경에서 오는 경우, 스레드는 파이썬에서 약간 다르게 작동합니다. 파이썬에서는 주어진 시간에 하나의 스레드 만 실행 상태에있을 수 있습니다. 즉, 설계 상 스레드가 여러 코어에서 병렬로 실행될 수 없기 때문에 파이썬의 스레드는 여러 처리 코어의 성능을 진정으로 활용할 수 없습니다.

python의 메모리 관리는 스레드로부터 안전하지 않으므로 각 스레드는 Python 인터프리터의 데이터 구조에 대한 배타적 액세스가 필요합니다.이 배타적 액세스는 GIL (글로벌 인터프리터 잠금) .

Why does python use GIL?

여러 스레드가 동시에 인터프리터 상태에 액세스하여 인터프리터 상태를 손상시키는 것을 방지합니다.

아이디어는 스레드가 실행될 때마다 (메인 스레드 인 경우에도) GIL을 획득하고 미리 정의 된 시간 간격 후에 GIL은 현재 스레드에 의해 해제되고 다른 스레드 (있는 경우)에 의해 다시 획득됩니다.

Why not simply remove GIL?

GIL을 제거하는 것이 불가능한 것은 아닙니다. 그렇게함으로써 우리는 액세스를 직렬화하기 위해 인터프리터 내부에 여러 개의 잠금을 두게되므로 단일 스레드 애플리케이션도 성능이 저하됩니다.

따라서 GIL 제거 비용은 결코 바람직하지 않은 단일 스레드 애플리케이션의 성능 저하로 보상됩니다.

So when does thread switching occurs in python?

GIL이 해제되면 스레드 스위치가 발생하는데 GIL은 언제 해제됩니까? 고려해야 할 두 가지 시나리오가 있습니다.

스레드가 CPU 바운드 작업을 수행하는 경우 (Ex 이미지 처리)

이전 버전의 python에서 스레드 전환은 고정 된 Python 지침 이후에 발생했지만 기본적으로 100 로 설정되어 있습니다. 단일 명령을 실행하는 데 소요되는 시간이 밀리 초에서 1 초까지 매우 거칠기 때문에 실행하는 데 걸리는 시간에 관계없이 모든 100 명령 후에 GIL을 릴리스하는 것은 좋지 않은 정책입니다.

새 버전에서는 스레드 전환을위한 측정 항목으로 명령어 수를 사용하는 대신 구성 가능한 시간 간격이 사용됩니다. 기본 전환 간격은 5 밀리 초입니다. 를 사용하여 현재 전환 간격을 가져올 수 있습니다. sys.getswitchinterval() . sys.setswitchinterval() 를 사용하여 변경할 수 있습니다.

스레드가 IO 바운드 작업 (Ex 파일 시스템 액세스 또는
네트워크 IO)

GIL은 스레드가 IO 작업이 완료 될 때까지 대기 할 때마다 해제됩니다.

Which thread to switch to next?

통역사에는 자체 스케줄러가 없습니다. 간격이 끝날 때 예약되는 스레드는 운영 체제의 결정입니다. .

여러 작업의 모습을 보여주기 위해 GIL이 자주 폴링하도록 설정되어 있음을 기억하십시오.이 설정은 미세 조정할 수 있지만 스레드가 수행하는 작업이 있거나 많은 컨텍스트 전환이 문제를 일으킬 것이라는 제안을 제공합니다.

나는 프로세서에 여러 부모를 제안하고 동일한 코어에서 같은 작업을 유지하려고 노력합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top