>  기사  >  백엔드 개발  >  Python 스레드 풀에 대한 추가 이해

Python 스레드 풀에 대한 추가 이해

高洛峰
高洛峰원래의
2016-10-19 15:13:131257검색

스레드 풀의 개념은 무엇인가요?

객체 지향 프로그래밍에서 객체를 생성하고 삭제하는 데는 시간이 많이 걸립니다. 객체를 생성하려면 메모리 리소스나 기타 추가 리소스를 확보해야 하기 때문입니다. 이는 특히 Java에서 가상 머신이 모든 객체를 추적하여 객체가 삭제된 후 가비지 수집될 수 있도록 시도하는 경우에 해당됩니다. 따라서 서비스 프로그램의 효율성을 높이는 한 가지 방법은 생성 및 소멸되는 객체의 수를 최대한 줄이는 것입니다. 특히 일부 리소스 집약적인 객체의 생성 및 소멸은 더욱 그렇습니다. 기존 객체를 활용하여 서비스를 제공하는 방법은 해결해야 할 핵심 문제입니다. 실제로 이것이 일부 "자원 공유" 기술이 등장한 이유입니다.

스레드 풀은 많은 스레드를 저장하는 단위이며, 이에 상응하는 작업 대기열도 있다는 것을 알고 있습니다. 전체 실행 프로세스는 실제로 스레드 풀의 제한된 스레드를 사용하여 작업 대기열의 작업을 완료하는 것입니다. 이 방법의 장점은 100번째 작업을 수행하기 위해 100번째 스레드를 생성할 때 이전 50개의 스레드가 작업을 완료했을 수 있으므로 각 작업마다 스레드를 생성할 필요가 없다는 것입니다. 따라서 스레드는 작업을 수행하고 시스템 리소스의 오버헤드를 줄이기 위해 재사용됩니다.

1층에서 2층으로 이동해야 하는 컴퓨터 메인프레임이 100개 있다는 것은 부적절한 비유입니다. 이동을 돕기 위해 100명을 부를 필요는 없습니다. 아니면 20명이면 한 사람당 10명, 5명이 배정되고, 더 빨리 움직이는 사람도 완료 여부를 알 수 없을 때까지 더 많이 움직일 것입니다. (이런 비유는...)

어쨌든 저는 Thread Pool의 개념을 대체적으로 이해하고 있습니다. 그렇다면 파이썬에서는 어떻게 구현할까요?

코드는 다음과 같습니다

# !/usr/bin/env python
# -*- coding:utf-8 -*-
# ref_blog:http://www.open-open.com/home/space-5679-do-blog-id-3247.html
import Queue
import threading
import time
class WorkManager(object):
    def __init__(self, work_num=1000,thread_num=2):
        self.work_queue = Queue.Queue()
        self.threads = []
        self.__init_work_queue(work_num)
        self.__init_thread_pool(thread_num)
    """
        初始化线程
    """
    def __init_thread_pool(self,thread_num):
        for i in range(thread_num):
            self.threads.append(Work(self.work_queue))
    """
        初始化工作队列
    """
    def __init_work_queue(self, jobs_num):
        for i in range(jobs_num):
            self.add_job(do_job, i)
    """
        添加一项工作入队
    """
    def add_job(self, func, *args):
        self.work_queue.put((func, list(args)))#任务入队,Queue内部实现了同步机制
    """
        检查剩余队列任务
    """
    def check_queue(self):
        return self.work_queue.qsize()
    """
        等待所有线程运行完毕
    """ 
    def wait_allcomplete(self):
        for item in self.threads:
            if item.isAlive():item.join()
class Work(threading.Thread):
    def __init__(self, work_queue):
        threading.Thread.__init__(self)
        self.work_queue = work_queue
        self.start()
    def run(self):
        #死循环,从而让创建的线程在一定条件下关闭退出
        while True:
            try:
                do, args = self.work_queue.get(block=False)#任务异步出队,Queue内部实现了同步机制
                do(args)
                self.work_queue.task_done()#通知系统任务完成
            except Exception,e:
                print str(e)
                break
#具体要做的任务
def do_job(args):
    print args
    time.sleep(0.1)#模拟处理时间
    print threading.current_thread(), list(args)
if __name__ == '__main__':
    start = time.time()
    work_manager =  WorkManager(10, 2)#或者work_manager =  WorkManager(10000, 20)
    work_manager.wait_allcomplete()
    end = time.time()
    print "cost all time: %s" % (end-start)

이 코드는 명확하고 이해하기 쉽습니다.

전체 코드에는 WorkManager와 Work의 두 가지 클래스만 있습니다. 전자는 이름에서 알 수 있듯이 스레드 풀과 작업 대기열을 관리하는 관리자이고 후자는 특정 스레드입니다.

전체 운영 논리는 지정된 수의 작업과 스레드를 WorkManager에 할당한 다음 각 스레드는 작업 대기열에서 작업을 가져와 대기열에 작업이 없을 때까지 실행하는 것입니다. Queue의 내부 동기화 메커니즘도 여기에 사용됩니다(동기화 메커니즘에 대해서는 아직 연구하지 않았습니다).

이러한 스레드 풀의 역할을 요약하자면, 원래 목적으로는 절대 사용하지 않을 것입니다. 웹 페이지에서 스레드의 시작과 중지를 제어해야 하는데 이 스레드 풀은 동시에 작업을 완료하는 데 사용됩니다. 하지만 스레드를 제어하는 ​​데에는 아무런 효과가 없지만 동시에 작업을 실행하는 역할은 꽤 좋고 웹 페이지를 크롤링하는 데 사용될 수 있다고 생각합니다.


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.