Python解释器设计了GIL(GlobalInterpreterLock)全局锁,使得多线程无法利用多核。Python实际上运行在单核CPU上。由于GIL全局锁的存在,python中多线程只是交替执行,在4核和8核CPU上只能使用1核。本文所讨论的python多线程是基于单核CPU实现线程交替执行,提高计算效率。优点:1.计算速度快2.共享内存和变量,资源消耗少threadingthread模块threading重点在Thread模块importthreading目标函数可以实例化一个Thread对象,每个Thread对象代表一个线程,可以通过start()方法启动线程。classthreading.Thread(group=None,target=None,name=None,args=(),kwargs={},*,daemon=None)Queue队列模块队列分为几种类型:FIFOLIFOPRIORTYFIFO表示FirstinFirstOut,先进先出。Queue提供了一个基本的FIFO容器,使用起来非常简单。maxsize是一个整数,表示队列中可以存放的数据条数的上限。一旦达到上限,插入就会造成阻塞,直到队列中的数据被消费完。如果maxsize小于或等于0,则队列大小不受限制。LIFO代表后进先出,后进先出。和栈类似,使用起来也很简单,maxsize的用法和上面一样。PRIORTY构造一个优先级队列。maxsize的用法同上。基本方法:Queue.Queue(maxsize=0)先进先出,如果maxsize小于1,表示队列长度无限Queue.LifoQueue(maxsize=0)LIFO,如果maxsize小于1,表示队列长度为infiniteQueue.qsize()返回队列的大小Queue.empty()如果队列为空,返回True,否则返回FalseQueue.full()如果队列满,返回True,否则FalseQueue.get([block[,超时]])读队列,超时等待时间Queue.put(item,[block[,timeout]])写队列,超时等待时间Queue.queue.clear()清空队列tast_done()表示任务入队之前已经完成。由队列的使用者线程调用。每个get()调用都会获得一个任务,随后的task_done()调用会告诉队列该任务已经处理完毕。如果当前join()处于阻塞状态,它将在队列中的所有任务都处理完后恢复执行(即,由put()调用入队的每个任务都有一个相应的task_done()调用)。上面介绍了多线程和队列的过程,现在开始实现python多线程程序。效果#!/usr/bin/python#-*-coding:UTF-8-*-importtimeimportthreadingfromqueueimportQueueclassWorker(threading.Thread):def__init__(self,selfManager,name):threading.Thread.__init__(self)self.work_queue=selfManager.work_queueself.name=nameself.start()defrun(self):whileTrue:try:ifself.work_queue.empty():#print("thread-%s:queueis空,等待任务。"%self.name)continuetext=self.work_queue.get(block=True)#todoAnythingprint("%sthread-%s:doingtasktext:%s"%(str(time.strftime("%Y-%m-%d%H:%M:%S",time.localtime())),self.getName(),str(text)))time.sleep(10)自我。work_queue.task_done()除了Exceptionase:print("thread-%s:taskiserror:%s"%(self.getName(),str(e)))breakclassWorkManager:def__init__(self,thread_num):self.work_queue=Queue()#队列对象self.threads=[]self._init_thread_pool(thread_num)def_init_thread_pool(self,thread_num):"""Initializethread"""fornameinrange(thread_num):self.threads.append(Worker(self,str(name)))defadd_job(self,job):"""初始化工作队列"""self.work_queue.put(job)if__name__=='__main__':work_manager=WorkManager(5)foriinrange(100):work_manager.add_job(i)完整源码跟贴公众号(后台回复python)
