Python3.2中引入的concurrent非常的好用,只用几行代码就可以编写出线程池/进程池,并且计算型任务效率和mutiprocessing.pool提供的poll和ThreadPoll相比不分伯仲,而且在IO型任务由于引入了Future的概念效率要高数倍。
而threading的话还要自己维护相关的队列防止死锁,代码的可读性也会下降,相反concurrent提供的线程池却非常的便捷,不用自己操心死锁以及编写线程池代码,由于异步的概念IO型任务也更有优势。
既然如此,如果不是为了向下兼容2.x,是不是可以完全没有必要继续使用mutiprocessing和threading了?concurrent如此的优秀。
Concurrent는 실제로 매우 유용하며 주로 ThreadPoolExecutor 및 ProcessPoolExecutor를 제공합니다. 멀티 스레드, 멀티 프로세스. 그러나 동시성은 본질적으로 스레딩과 다중 처리를 캡슐화한 것입니다. 소스코드를 보면 알 수 있습니다.
ThreadPoolExecutor는 자체 작업 대기열을 제공하므로 직접 작성할 필요가 없습니다. 소위 스레드 풀은 단순히 현재 스레드 수를 정의된 max_workers 크기와 비교합니다. 크기가 max_workers보다 작으면 작업을 실행하기 위한 스레드를 생성할 수 있습니다. 소스코드를 보실 수 있습니다
def _adjust_thread_count(자체):
으아아아따라서 대기열을 직접 관리한다면 문제가 되지 않습니다. Cocurrent도 내부적으로 대기열을 관리하고 있으며, 이는 귀하를 위해 작성됩니다.
으아아아교착 상태 문제의 경우 동시 사용으로 인해 교착 상태 문제가 발생할 수도 있습니다. 예를 들어보고 실행해 보세요
ProcessPoolExecutor는 내부적으로 다중 처리도 사용합니다. 멀티 코어의 특성을 최대한 활용하고 GIL의 제한 사항을 없앨 수 있습니다. ProcessPoolExecutor(max_workers=2)를 정의할 때 max_workers는 CPU 코어 수보다 약간 크며 너무 클 수 없습니다. ProcessPoolExecutor는 작업 대기열을 유지하기 위해 내부적으로 call_queue를 유지하며 해당 유형은 multiprocessing.Queue입니다. 큐를 관리하는 스레드도 있습니다. 이는 병류의 최적화라고 할 수 있습니다.
으아아아자세한 내용은 소스 코드를 볼 수 있습니다. self._adjust_process_count()는 실제로 작업을 실행하는 프로세스를 시작합니다. _adjust_process_count를 클릭하면 알 수 있습니다. self._queue_management_thread는 대기열을 관리하는 스레드입니다
그래서 Cocurrent는 사용하기 쉽습니다. 즉, 대기열 유지 및 대기열 스레드 관리와 같은 자체적으로 더 나은 처리를 수행하므로 더 이상 걱정할 필요가 없습니다. 물론 직접 구현할 수도 있습니다. 이는 동시 전류를 사용하여 달성할 수 있습니다. 이는 스레딩 및 다중 처리를 통해 달성할 수 있으며, 기껏해야 추가 작업을 직접 수행해야 합니다. 왜냐하면 Cocurrent는 본질적으로 이 두 개의 코어를 사용하기 때문입니다. 물론 이미 사용 가능한 더 나은 병류가 있다면 직접 바퀴를 재발명하는 대신 직접 사용할 수 있는 것이 가장 좋습니다. 따라서 어떤 것을 사용할지는 개인의 친숙도에 따라 다릅니다. 예를 들어 저는 python2를 사용하지만 cocurrent를 사용할 수 없습니다. 스레딩을 사용해야했습니다.
위 분이 이미 명확하게 말씀하셨는데, 조금 추가하고 싶습니다.
Concurrent.future는 스레드/프로세스를 관리하기 위해 비동기 개념을 사용하지만 실제로는 비동기 IO를 캡슐화하지 않으므로 질문자는 IO 효율성 향상이 실제로 잘못된 것이라고 말했습니다.
Concurrent는 스레드가 아닌 코루틴이며 두 가지 개념입니다.