赞
踩
首先先来介绍下queue这个包吧,这个包叫队列,没错,就是那个和栈反过来的那个队列,大家一听队列就随口说出先进先出,而栈则是后进先出,为什么要用用队列来实现,其实我也不知道,反正用过之后很顺手,具体哪里也说不上来
先来看下队列的内置方法的,我们只需要记住两个,一个是put 放 ,另一个是get 获得,因为我们q = queue.Queue()创建了一个队列后,这个队列是空的,要先放东西进去才能从里面拿东西出来
q = queue.Queue()
q.qsize() 返回队列的大小
q.empty() 如果队列为空,返回True,反之False
q.full() 如果队列满了,返回True,反之False
q.full 与 maxsize 大小对应
q.get([block[, timeout]]) 获取队列,timeout等待时间
q.get_nowait() 相当q.get(False)
q.put(item) 写入队列,timeout等待时间
q.put_nowait(item) 相当q.put(item, False)
q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号
q.join() 实际上意味着等到队列为空,再执行别的操作
下面是我自己写的一个简单的代码,我会用文字来注释,以便大家能看懂,真心简单,熟悉读完这篇文章后你如果还不会的话,那我也没什么说的了
- #开启多个线程,同时执行任务,有几个线程就执行几个任务
-
- import threading
- import time
- import queue
-
- class MyThread(threading.Thread):
- def __init__(self, func):
- threading.Thread.__init__(self)
- self.func = func
- def run(self):
- self.func()
-
- def worker():
- while not q.empty():
- item = q.get() # 或得任务
- print('Processing : ',item)
- time.sleep(1)
-
- def main():
- threads = []
- for task in range(100):
- q.put(task)
- for i in range(threadNum): #开启三个线程
- thread = MyThread(worker)
- thread.start()
- threads.append(thread)
- for thread in threads:
- thread.join()
-
- if __name__ == '__main__':
- q = queue.Queue()
- threadNum = 3
- main()

看代码先看主入口,根据里面的函数调用一步步来
1. 首先我实例化了一个队列 q = queue.Queue() ,然后我设置线程数为3,接着调用main() 方法
2. 进入main函数中,我创建了一个空列表,用来放线程,第一个for 循环中我做的是将(0,100)之间数据放入队列当中,当然,100是取不到的,放完队列后又来了个for循环,这个for循环是用来创建线程的,前面说了threadNum = 3,那么说明我这里要循环三次,threadNum的值分别为0,1,2,当然,这三个数用不到,因为我没在MyThread写线程名,没有把thread作为参数传入类中,所以每个线程都是无名氏,我们看到thread = MyThread(worker) 这段代码,先来看MyThread这个类,worker这个参数先不看,MyThread中这个类继承了threading.Thread,在init方法中初始化了父类,也就是threading.Thread,并且定义了一个属性,属性名叫func,因为threading这个类有自己的run方法,我们可以重写父类的run方法,self.func() 表明但我们start后,线程会自动调用run方法,就会执行self.func() 这句
3. 看完MyThread这个类后我们就来看worker这个参数,有的人就会问,看了半天没看到有这个参数啊,谁说参数一定是变量啊,也有可能是函数啊,现在就有人恍然大悟了,看到worker这个方法。这个方法里面一个while循环,我使用的一个队列的方法,这个方法是q.empty(),这个方法说明当队列q为空时,他的值为True,前面写了个not ,说明整句的意思是,当队列q不为空时才会执行这个while循环。一开始定义一个变量item 来接收得到的数据,打印一遍并且休眠一秒,不休眠的话程序运行太快,看不到多线程的效果,以上 thread = MyThread(worker) 这句代码就解释完了
4. thread.start() 这句是启动线程,threads.append(thread)是将线程加入到前面定义的threads空列表中,最后这个for循环是将每个线程都join()一下,join的意思是等线程结束后才会执行后面的语句,我们这里的意思是前面三个线程跑完了才能轮到后面三个线程
5. 基本的代码都讲解完毕了,现在来运行代码
就会发现,一次输出三句,停顿一秒后又输出三句,因为开了三个线程,有兴趣的可以把我代码复制下来并且将线程数改下来看下效果,看到这估计有人就明白了,这个queue队列相当于或类似一个全局的列表,只负责存和取,没错,他的作用就是这样,最起码我用的只有这么多
下面还有一个列子,这个列子是我想执行一个永不停止的线程,每次队列被取完后,我都会将数据原样放回去,具体的步骤我就不说了,上面有写
- import threading
- import queue
- import time
-
- class Mythread(threading.Thread):
- def __init__(self,fun):
- threading.Thread.__init__(self)
- self.fun = fun
- def run(self):
- self.fun()
-
- def worker():
- global data
- while True:
- if not q.empty():
- a = q.get()
- parse(a[0], a[1])
- time.sleep(1)
- data.append(a)
- else:
- for i in data:
- q.put(i)
- data = []
-
-
- def parse(qd, zd):
- mystr = qd + zd
- print('=============',mystr)
-
- def main():
- threads = []
- for i in LstAdd:
- q.put(i)
- for i in range(thendNum):
- thread = Mythread(worker)
- thread.start()
- threads.append(thread)
- for thread in threads:
- thread.join()
-
- if __name__ == '__main__':
- LstAdd = [
- ('abcde1','adfa1'),
- ('abcde2','adfa2'),
- ('abcde3','adfa3'),
- ('abcde4','adfa4'),
- ('abcde5','adfa5'),
- ('abcde6','adfa6'),
- ('abcde7','adfa7'),
- ('abcde8','adfa8'),
- ('abcde9','adfa9'),
- ]
- data = []
- q = queue.Queue()
- thendNum = 3
- main()

我想将列表中每个元素即元组的两个元素相加并输出,运行程序结果如下:
他会一直输出1-9,后面的没有截图下来,太多了,我将每次get()的数据都存起来,这样防止数据丢失,每次我都会判断队列是否为空,为空的话就将存起来的数据原样存回去,并且情况存这些数据的列表,保证每次都是同样的数据同样的顺序
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。