파이썬에서 다중 스레드 대신 다중 프로세스를 사용하는 것이 권장되는 이유는 무엇입니까?
1 이란 무엇입니까? 길?
GIL 의 전체 이름은 글로벌 인터프리터 잠금 (Global Interpreter Lock) 으로, python 설계 초기 고려사항과 데이터 보안을 위한 결정에서 비롯됩니다.
2. CPU 당 한 번에 하나의 스레드만 실행할 수 있습니다.
사실, 싱글 코어 CPU 아래의 멀티 스레드는 병렬 처리가 아니라 동시성에 불과합니다. 동시 및 병렬 처리 모두 여러 요청을 동시에 처리하는 개념입니다. 그러나 동시성과 병행은 차이가 있다. 평행은 둘 이상의 이벤트가 동시에 발생한다는 것을 의미합니다. 동시성은 둘 이상의 이벤트가 같은 시간 간격 내에 발생한다는 것을 의미합니다.
파이썬 멀티 스레딩에서 각 스레드의 실행 모드는 다음과 같습니다.
길 찾으러 가요
수면 또는 파이썬 가상 머신이 일시 중지될 때까지 코드를 실행합니다.
GIL 해제
스레드가 실행되려면 먼저 GIL 을 받아야 합니다. 우리는 GIL 을' 통행증' 으로 볼 수 있지만 파이썬 프로세스에는 GIL 이 하나밖에 없습니다. 통과 할 수없는 스레드는 CPU 실행에 들어갈 수 없습니다.
Python2.x 에서 GIL 의 해제 논리는 현재 스레드에서 입출력 작업이 발생했거나 ticks 개수가100 에 도달했다는 것입니다. Ticks 는 Python 자체의 카운터로 볼 수 있으며, GIL 에만 적용되며, 각 해제 후 0 이 될 때마다 Sys.set 을 통과할 수 있습니다.
그러나 GIL 잠금이 해제될 때마다 스레드는 잠금을 놓고 스레드를 전환하므로 리소스가 소모됩니다. 또한 python 의 프로세스는 GIL 잠금의 존재로 인해 동시에 하나의 스레드만 실행할 수 있습니다 (GIL 을 얻는 스레드는 실행만 가능). 이는 python 멀티 스레드 효율성이 멀티코어 CPU 에서 높지 않은 이유입니다.
그럼 파이썬의 멀티 스레딩은 완전히 쓸모가 없나요?
여기서 우리는 분류에 대해 논의합니다.
CPU 집약형 코드 (다양한 루프 처리, 개수 등). ), 이 경우 계산 작업이 과중하기 때문에 틱톡 수가 곧 임계값에 도달하고 GIL 의 석방과 재경쟁 (여러 스레드를 앞뒤로 전환하는 것은 물론 자원을 소모하는 것) 을 트리거하기 때문에 python 아래의 멀티 스레드는 CPU 집약적인 코드에 친숙하지 않습니다.
입출력 집약적 코드 (파일 처리, 웹 크롤러 등) 의 경우 ), 멀티 스레딩은 효율성을 효과적으로 향상시킬 수 있습니다 (단일 스레드에 입출력 작업이 있는 경우 IO 를 기다리며 불필요한 시간 낭비를 초래할 수 있습니다. 멀티 스레딩을 켜면 스레드 A 가 기다리는 동안 자동으로 스레드 B 로 전환할 수 있습니다. CPU 자원을 낭비하지 않고 프로그램 실행 효율성을 높일 수 있습니다.) 그래서 python 의 멀티 스레드는 IO 집약적인 코드에 우호적이다.
Python3.x 에서 GIL 은 ticks (실행 시간이 임계값에 도달하면 현재 스레드가 GIL 을 해제) 대신 타이머를 사용하여 CPU 사용량이 많은 프로그램에 더 친숙하지만 GIL 은 한 번에 하나의 스레드만 실행할 수 있는 문제를 해결하지 못해 효율성이 떨어집니다.
참고: 멀티 코어 멀티 스레딩은 싱글 코어 멀티 스레딩보다 나쁩니다. 싱글 코어 멀티 스레딩은 GIL 을 해제할 때마다 GIL 잠금을 획득할 수 있으므로 원활하게 실행할 수 있기 때문입니다. 하지만 멀티코어에서는 CPU0 이 GIL 을 풀면 다른 CPU 의 스레드가 경쟁하지만, GIL 은 즉시 CPU0 에 의해 획득될 수 있으며, 이로 인해 다른 CPU 에서 깨어난 스레드가 깨어나고 전환 시간이 지나서야 예정된 상태로 전환되어 스레드 충돌 (thr) 이 발생할 수 있습니다.
원래 질문으로 돌아가기: python 에서 멀티코어 CPU 를 최대한 활용하려면 멀티프로세스를 사용해야 한다는 베테랑의 말을 자주 듣습니다. 왜요
그 이유는 각 프로세스마다 독립적인 GIL 이 있고 서로 간섭하지 않기 때문에 진정한 병렬 실행이 가능하기 때문에 python 에서 다중 프로세스는 멀티 스레드 (멀티 코어 CPU 만 해당) 보다 더 효율적으로 실행됩니다.
따라서 멀티 코어에서 병렬 효율성을 향상시키는 일반적인 방법은 멀티 프로세스를 사용하여 실행 효율성을 효과적으로 향상시키는 것입니다.