이것이 필요한 이유는 GPRS 모뎀이 연결된 1000 개의 장치에서 데이터를 폴링해야하고이 장치에 대한 클라이언트 프로토콜 구현에 차단 API가 있기 때문입니다.
<data> = protocol.get_<some_data>(stream)
모든 get 메서드는 차단됩니다. 데이터를 반환하거나 예외를 발생시킬 수만 있습니다. Stream은 GPRS 모뎀에서 앱으로 설정된 TCP 소켓 연결입니다. 프로토콜은 파이썬으로 구현됩니다. 프로토콜의 복잡성은 설명하기 어렵습니다. 특정 기능을 가진 약 100 가지 유형의 장치가 있으며 get 메소드가이를 인식하므로 프로토콜 구현은 예를 들어 go 또는 erlang으로 이식하는 것이 매우 복잡합니다 (이에 대해 그러한 금액을 요구할 것입니다). 내 상사가 울 것입니다). 따라서 질문은 파이썬에서 1000 스레드를 유지하는 방법처럼 들릴 수 있습니다. 나는 GIL (나는 현재 CPython을 사용한다)뿐만 아니라 OS가 제 3 차 세계 대전이 시작되었다고 느끼기 때문에 파이썬 가능성을 훨씬 뛰어 넘을 수 있다는 것을 알고 있습니다 (이 모든 것을 하나의 서버 시스템에서 가져올 계획이었습니다).
블로킹 I / O 만 사용해야한다고 가정하면 (예 : 비 블로킹 I / O를 사용하기 위해 다시 작성하기에는 너무 많은 기존 코드베이스가 있기 때문에) 가장 쉬운 방법은 단순히 1000 개의 스레드를 생성하는 것입니다. 대부분의 OS는 많은 스레드를 처리 할 수 있으며 (비록 효율적으로 수행 할 수는 없지만) I / O를 기다리는 차단 된 스레드가 GIL을 보유하지 않기 때문에 GIL은 문제가되지 않습니다. (GIL은 CPU 바운드 계산을 병렬화하여 속도를 높이려는 경우에만 문제이며 모든 스레드가 I / O 바운드 인 것처럼 들립니다)
1000 개의 스레드가있는 프로세스가 실제로 선택한 OS에 너무 많은 스레드가 허용 가능하게 처리된다는 사실을 발견하면 항상 스레드를 여러 프로세스로 나눌 수 있습니다 (예 : 각각 100 개의 스레드가있는 10 개의 프로세스 또는 작동하는 다른 비율). 베스트). 그런 다음 문제가 전역 스레드 제한 문제로 판명되면 (예 : 프로세스 수에 관계없이 1000 개의 스레드가 너무 많음) 다음으로 할 수있는 일은 여러 컴퓨터에 분산시키는 것입니다 (예 : 10 각각 100 개의 스레드를 실행하는 컴퓨터).
하지만 이것들은 모두 추악한 해결책입니다. 실제 해결책은 각 스레드가 (잠재적으로 많은) 소켓 수를 동시에 처리 할 수 있도록 비 블로킹 I / O를 사용하도록 프로그램을 다시 작성하는 것입니다. 아직 읽지 않았다면 많은 동시 TCP 연결을 잘 지원하는 주제에 대한 C10K 문제 기사 를 읽고 싶을 수 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다