python多线程队列文件_二十三、Python队列实现多线程(下篇)

「@Author:Runsen」

在Python中,主要采用队列和线程的方法来实现多线程。

队列

队列(queue),是先进先出(FIFO, First-In-First-Out)的线性表,在具体应用中通常用链表或者数组来实现,队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作,队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加。

470eff2c505e6c8a75b670116ad30038.png

在Python中队列可以通过内置模块queue导入,具体导入方法:from queue import Queue。

queue

queue模块提供了适合多线程编程的先进先出的数据结构,可以用来在生产者和消费者线程之间安全的传递消息或者数据;锁是调用方处理,因此多线程可以安全、方便的使用同一队列实现。

0e54899f0acd8535539ec2b2336aaf2d.png

常用属性和方法:

接口

描述

put(x)

入队

get()

出队

empty()

判断队列是否为空

full()

判断队列是否未满

qsize()

队列的当前长度

task_done()

任务结束

join()

等待完成

Queue类实现了一个基本的先进先出容器。使用put方法将元素增加到序列的一端,使用get方法从另一端删除,具体代码如下。

import queue

q = queue.Queue()

#添加元素

for i in range(5):

q.put(i)

#删除元素

while not q.empty():

print(q.get())

运行上面的程序,你将会看到下面的输出:

0

1

2

3

4

生产者/消费者模式

我们经常会遇到这样的一个问题,这里有成千上万条数据,每次需要取出其中的一条数据进行处理,那么引入多线程该怎么进行任务分配?

我们可以将数据进行分割然后交给多个线程去跑,因为线程间数据的共享的问题。

它包含两类进程:一种只是用来生产数据,例外一种只是用来消费数据.为了串联他们,通常会采用共享的数据区域,就像一个仓库.生产者产生的数据都放入仓库中并不需要关注消费者的行为,消费者只需要从共享仓库中获取数据,并不需要关心生产者的行为.

# -*- coding:utf-8 -*-

# time :2019/4/23 10:13

# Author: Maoli

import threading

import time

import random

MONEY = 0

gLock = threading.Lock()

def Procuder():

while True:

global MONEY

random_money = random.randint(10,100)

gLock.acquire() #加锁

MONEY += random_money

gLock.release() #释放锁

print ('生产者%s-生产了%d' % (threading.current_thread,random_money))

time.sleep(0.5)

def Customer():

while True:

global MONEY

random_money = random.randint(10,100)

if MONEY > random_money:

print ('消费者%s-消费了:%d' % (threading.current_thread,random_money))

gLock.acquire()

MONEY -= random_money

gLock.release()

else:

print ('需要消费的钱为:%d,余额为:%d,' % (random_money,MONEY))

time.sleep(0.5)

def p_c_test():

# 执行3个线程,来当作生产者

for x in range(3):

th = threading.Thread(target=Procuder)

th.start()

# 执行3个线程,来当作消费者

for x in range(3):

th = threading.Thread(target=Customer)

th.start()

if __name__ == "__main__":

p_c_test()

运行截图如下:

de111c35d8fee07a75476b072917efdf.png

队列实现多线程

在这里我们可以使用队列与线程相结合的方式进行任务分配。在生产消费者模式当中用到的是阻塞型queue。在Python当中,我们最常用的queue就是一个支持多线程场景的阻塞队列

队列线程的思想:首先创建一个全局共享的队列,队列中只存在有限个元素,并将所有的数据逐条加入到队列中,并调用队列的join函数进行等待。之后便可以开启若干线程,线程的任务就是不断的从队列中取数据进行处理就可以了。

# -*- coding:utf-8 -*-

# time :2019/4/23 10:35

# Author: Maoli

import threading

import time

import queue

# 下面来通过多线程来处理Queue里面的任务:

def work(q):

while True:

if q.empty():

return

else:

t = q.get()

print("当前线程sleep {} 秒".format(t))

time.sleep(t)

def main():

q = queue.Queue()

for i in range(5):

q.put(i)  # 往队列里生成消息

thread_num = 5

threads = []

for i in range(thread_num):

t = threading.Thread(target=work, args=(q,))

# args需要输出的是一个元组,如果只有一个参数,后面加,表示元组,否则会报错

threads.append(t)

# 创建5个线程

for i in range(thread_num):

threads[i].start()

for i in range(thread_num):

threads[i].join()

if __name__ == "__main__":

start = time.time()

main()

print('耗时:', time.time() - start)

运行上面的程序,你将会看到下面的输出:

当前线程sleep 0 秒

当前线程sleep 1 秒

当前线程sleep 2 秒

当前线程sleep 3 秒

当前线程sleep 4 秒

耗时:4.002955436706543

今天也学到了很多东西呢,明天有什么新知识呢?真期待鸭~如果喜欢文章可以关注我哦~

本文已收录 GitHub,传送门~[1] ,里面更有大厂面试完整考点,欢迎 Star。

Reference

[1]

传送门~: https://github.com/MaoliRUNsen/runsenlearnpy100

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值