python多线程queue_Python中Queue模块及多线程使用

Python的Queue模块提供一种适用于多线程编程的FIFO实现。它可用于在生产者(producer)和消费者(consumer)之间线程安全(thread-safe)地传递消息或其它数据,因此多个线程可以共用同一个Queue实例。Queue的大小(元素的个数)可用来限制内存的使用。

Basic FIFO Queue

Queue类实现了一个基本的先进先出(FIFO)容器,使用put()将元素添加到序列尾端,get()从队列尾部移除元素。

LIFO Queue

与标准FIFO实现Queue不同的是,LifoQueue使用后进先出序(会关联一个栈数据结构)。

Priority Queue(优先队列)

除了按元素入列顺序外,有时需要根据队列中元素的特性来决定元素的处理顺序。例如,财务部门的打印任务可能比码农的代码打印任务优先级更高。PriorityQueue依据队列中内容的排序顺序(sort order)来决定那个元素将被检索。

Using Queues with Threads

queue介绍

queue是python中的标准库,俗称队列,可以直接import 引用,在python2.x中,模块名为Queue

在python中,多个线程之间的数据是共享的,多个线程进行数据交换的时候,不能够保证数据的安全性和一致性,所以当多个线程需要进行数据交换的时候,队列就出现了,队列可以完美解决线程间的数据交换,保证线程间数据的安全性和一致性

queue模块有三种队列及构造函数:

Python queue模块的FIFO队列先进先出。 class queue.Queue(maxsize)

LIFO类似于堆,即先进后出。 class queue.LifoQueue(maxsize)

还有一种是优先级队列级别越低越先出来。 class queue.PriorityQueue(maxsize)

queue模块中的常用方法:

queue.qsize() 返回队列的大小

queue.empty() 如果队列为空,返回True,反之False

queue.full() 如果队列满了,返回True,反之False

queue.full 与 maxsize 大小对应

queue.get([block[, timeout]])获取队列,timeout等待时间

queue.get_nowait() 相当queue.get(False)

queue.put(item) 写入队列,timeout等待时间

queue.put_nowait(item) 相当queue.put(item, False)

queue.task_done() 在完成一项工作之后,queue.task_done()函数向任务已经完成的队列发送一个信号

queue.join() 实际上意味着等到队列为空,再执行别的操作

代码例子:

#coding: utf-8

from queue importQueue#Queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递

deftest_queue():

q=Queue(10)for i in range(5):

q.put(i)while notq.empty():print(q.get())deftest_LifoQueue():importqueue#queue.LifoQueue() #后进先出->堆栈

q = queue.LifoQueue(3)

q.put(1)

q.put(2)

q.put(3)print(q.get())print(q.get())print(q.get())deftest_PriorityQueue():importqueue#queue.PriorityQueue() #优先级

q = queue.PriorityQueue(3) #优先级,优先级用数字表示,数字越小优先级越高

q.put((10, 'a'))

q.put((-1, 'b'))

q.put((100, 'c'))print(q.get())print(q.get())print(q.get())#Python queue队列,实现并发,在网站多线程推荐最后也一个例子,比这货简单,但是不够规范

from queue import Queue #Queue在3.x中改成了queue

importrandomimportthreadingimporttimefrom threading importThreadclassProducer(threading.Thread):"""Producer thread 制作线程"""

def __init__(self, t_name, queue): #传入线程名、实例化队列

threading.Thread.__init__(self, name=t_name) #t_name即是threadName

self.data =queue"""run方法 和start方法:

它们都是从Thread继承而来的,run()方法将在线程开启后执行,

可以把相关的逻辑写到run方法中(通常把run方法称为活动[Activity]);

start()方法用于启动线程。"""

defrun(self):for i in range(5): #生成0-4五条队列

print("%s: %s is producing %d to the queue!" % (time.ctime(), self.getName(), i)) #当前时间t生成编号d并加入队列

self.data.put(i) #写入队列编号

time.sleep(random.randrange(10) / 5) #随机休息一会

print("%s: %s producing finished!" % (time.ctime(), self.getName)) #编号d队列完成制作

classConsumer(threading.Thread):"""Consumer thread 消费线程,感觉来源于COOKBOOK"""

def __init__(self, t_name, queue):

threading.Thread.__init__(self, name=t_name)

self.data=queuedefrun(self):for i in range(5):

val=self.data.get()print("%s: %s is consuming. %d in the queue is consumed!" % (time.ctime(), self.getName(), val)) #编号d队列已经被消费

time.sleep(random.randrange(10))print("%s: %s consuming finished!" % (time.ctime(), self.getName())) #编号d队列完成消费

defmain():"""Main thread 主线程"""queue= Queue() #队列实例化

producer = Producer('Pro.', queue) #调用对象,并传如参数线程名、实例化队列

consumer = Consumer('Con.', queue) #同上,在制造的同时进行消费

producer.start() #开始制造

consumer.start() #开始消费

"""join()的作用是,在子线程完成运行之前,这个子线程的父线程将一直被阻塞。

join()方法的位置是在for循环外的,也就是说必须等待for循环里的两个进程都结束后,才去执行主进程。"""producer.join()

consumer.join()print('All threads terminate!')if __name__=="__main__":

test_queue()print("=====后进先出=====")

test_LifoQueue()print("=====优先级======")

test_PriorityQueue()

main()

线程模块

- 多线程主要的内容:直接进行多线程操作,线程同步,带队列的多线程;

Python3 通过两个标准库 _thread 和 threading 提供对线程的支持。

_thread 提供了低级别的、原始的线程以及一个简单的锁,它相比于 threading 模块的功能还是比较有限的。

threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法:

threading.currentThread(): 返回当前的线程变量。

threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。

threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:

run(): 用以表示线程活动的方法。

start():启动线程活动。

join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。

isAlive(): 返回线程是否活动的。

getName(): 返回线程名。

setName(): 设置线程名。

#queue 多线程各个线程的运算的值放到一个队列中,到主线程的时候再拿出来,以此来代替#return的功能,因为在线程是不能返回一个值的

# https://www.cnblogs.com/zephyr-1/p/6043785.html

importtimeimportthreadingfrom Queue importQueuedefjob(l,q):

q.put([i**2 for i inl])defmultithreading(data):

q=Queue()

threads=[]for i in xrange(4):

t= threading.Thread(target = job,args =(data[i],q))

t.start()

threads.append(t)for thread inthreads:

thread.join()

results=[]for _ in range(4):

results.append(q.get())printresultsif __name__ == "__main__":

data= [[1,2,3],[4,5,6],[3,4,3],[5,5,5]]

multithreading(data)

[[1, 4, 9], [16, 25, 36], [9, 16, 9], [25, 25, 25]]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值