python内置队列模块 queue

queue的四种队列

q = queue.Queue()           # 先进先出队列
q = queue.LifoQueue() # 后进先出队列
q = queue.PriorityQueue() # 优先级队列
q = queue.deque() # 双向队列

queue.Queue()先进先出队列

  • 基本使用方法
import queue

q = queue.Queue(maxsize=10)  # 创建一个先进先出的队列,maxsize为队列大小

q.put(11)       # 向队列添加数据
q.put(22, block=False) # 默认block=True,表示为阻塞状态,如果队列中已经满了,就一直处于阻塞(等待)状态,直到队列中有位置为止
# block=Flase,表示为非阻塞状态,当队列满了的时候直接报错 queue.Full
q.put(33, timeout=2) # timeout=2,当队列满了的时候,等待2秒,如果2秒后还是满的则报错 queue.Full print(q.qsize()) # 返回队列中当前的个数
print(q.empty()) # 查看队列是否为空,返回True表示为空,False表示不为空
print(q.full()) # 查看队列是否满了,返回True表示满了,False表示没满
q.get() # 从队列取数据,如果队列没有数据,一直处于阻塞状态,直到取到数据为止
q.get(timeout=2) # 取数据,timeout参考 q.put(timeout=2)
q.get_nowait() # 从队列取数据,不阻塞,调用 q.get(block=False)
  • join和task_done的组合
# 情景1   当队列中没有数据的时候该线程还是处于阻塞状态
import queue q = queue.Queue(maxsize=10) # 创建一个先进先出的队列,maxsize为队列大小 q.put("sss")
q.get() q.join() # 任务完成之后才结束,否则一直处于阻塞状态 # 情景2 当每次从队列取完数据,执行task_done方法后,才表示该任务结束了
import queue
q = queue.Queue(maxsize=10) # 创建一个先进先出的队列,maxsize为队列大小 q.put("sss")
q.put("sss")
q.put("sss") q.get()
q.task_done()
q.get()
q.task_done()
q.get()
q.task_done() q.join() # 任务完成之后才结束,否则一直处于阻塞状态()

queue.LifoQueue() 后进先出队列

  • 基本使用方法,该队列接继承先进先出队列,其他方法参考先进先出队列
import queue
q = queue.LifoQueue() # 创建一个后进先出的队列,该队列基础先进先出队列
q.put(123)
q.put(456)
value = q.get()
print(value)

queue.PriorityQueue() 优先级队列

  • 基本使用方法,该队列接继承先进先出队列,其他方法参考先进先出队列
import queue
q = queue.PriorityQueue()
q.put((1, "aaa"))
q.put((2, "bbb"))
q.put((3, "ccc"))
q.put((-100, "0000"))
value = q.get()
print(value)

queue.deque() 双向队列

  • 基本使用方法
q = queue.deque()
q.append("appendright") # 在队列右边添加一个元素
q.appendleft("appendleft") # 在队列左边添加一个元素
right_v = q.pop() # 在队列右边取出一个元素
left_v = q.popleft() # 在队列左边取出一个元素 print(right_v)
print(left_v)
  • 双向队列剩下的一些方法
clear()   				# 清空整个队列
count(value) # 查看value在队列中的次数
extend(iterable) # 在队列右侧添加一个可迭代的数据
extendleft(iterable) # 在队列左侧添加一个可迭代的数据
remove(value) # 删除队列中第一个value值
reverse() # 将队列进行反转
rotate()

多线程

基本使用

  • 创建多线程的两种模式

    • 使用threading.Thread创建多线程
    import threading
    
    def f1(arg):
    print(arg) t = threading.Thread(target=f1, args=[123,])
    t.start()
    • 通过自定义类创建多线程
    import threading
    
    def f2(arg):
    print(arg) class MyThread(threading.Thread): # 自定义类,并继承threading.Thread类
    def __init__(self, func, args):
    self.func = func
    self.args = args
    super(MyThread, self).__init__() def run(self): # run方法用来执行线程里面的func函数
    self.func(self.args) obj = MyThread(func=f2, args=123)
    obj.start()

线程锁 (Lock、RLock)

  • 在没有锁的情况下
import threading
import time NUM = 10 def func():
global NUM
NUM -= 1 time.sleep(2)
print(NUM) for i in range(10):
t = threading.Thread(target=func)
t.start() # 输出
0
0
0
0
0
0
0
0
0
0
  • 单个锁 (Lock)
import threading
import time NUM = 10 def func():
global NUM
lock.acquire() # 加锁
NUM -= 1 time.sleep(2)
print(NUM)
lock.release() # 解锁 lock = threading.Lock() # 创建锁的对象
for i in range(10):
t = threading.Thread(target=func)
t.start() # 输出
9
8
7
6
5
4
3
2
1
0
  • 多重锁 (RLock)
import threading
import time NUM = 10 def func():
global NUM
lock.acquire() # 加锁
NUM -= 1 time.sleep(2) lock.acquire() # 加锁
NUM += 3
time.sleep(1)
print(NUM)
lock.release() # 解锁
lock.release() # 解锁 lock = threading.RLock() # 创建锁的对象
for i in range(10):
t = threading.Thread(target=func)
t.start()

信号量(Semaphore)

同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。

import threading
import time def func(i):
sem.acquire() # 加锁
time.sleep(1)
print(i)
sem.release() # 解锁 maxThread = 5 # 定义最大线程数
semaphore = threading.BoundedSemaphore(maxThread) # 创建信号量对象,同时最多允许5个线程运行
for i in range(10):
t = threading.Thread(target=func, args=[i,])
t.start()

事件 (event)

python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。
事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么event.wait 方法时便不再阻塞。
  • clear:将“Flag”设置为False
  • set:将“Flag”设置为True
import threading

def func(i):
print(i)
event.wait() # 阻塞状态,等待event的flag变为True
print(i+100) event = threading.Event() # 创建event对象
for i in range(10):
t = threading.Thread(target=func, args=[i,])
t.start() event.clear() # 将event的flag变为flase inp = input(">>")
if inp == "1":
event.set() # 将event的flag变为True

条件 (Condition)

使得线程等待,只有满足某条件时,才释放n个线程
import threading

def func(i):
print(i)
con.acquire() # 加锁
con.wait() # 阻塞,等待notify方法执行唤醒该线程
print(i+100)
con.release() # 释放锁 con = threading.Condition()
for i in range(10):
t = threading.Thread(target=func, args=[i,])
t.start() while True:
inp = input(">>")
if inp == "q":
break
con.acquire() # 加锁
con.notify(int(inp)) # 激活int(inp)个线程执行
con.release() # 释放锁

计时器

定时器,指定n秒后执行某操作,主线程不阻塞
import threading

def hello():
print("hello, world") t = threading.Timer(2, hello)
t.start()
print("xxx")

自定义线程池

import queue
import threading
import time class ThreadPool: # 创建线程池类 def __init__(self, maxsize=5):
self.maxsize = maxsize
self._q = queue.Queue(maxsize) # 默认添加5个类名到队列中
for i in range(maxsize):
self._q.put(threading.Thread) def get_thread(self):
"""
从队列中取出一个线程名
:return:
"""
return self._q.get() def add_thread(self):
"""
向线程中添加一个线程名
:return:
"""
self._q.put(threading.Thread) def task(arg):
print(arg)
time.sleep(1)
pool.add_thread() # 当该任务完成时,调用add_thread()方法向队列中添加一个线程名 pool = ThreadPool(5) # 实例化线程池对象
for i in range(100):
t = pool.get_thread() # 调用get_thread()方法从队列中获取多线程名
obj = t(target=task, args=[i,]) # 执行多线程,生成线程对象
obj.start() # 将线程运行,等待cpu调度

生产者消费者模型(队列)

多进程

基本使用

多进程数据共享的三种方法

  • queues.Queue
from multiprocessing import Process
from multiprocessing import queues
import multiprocessing def foo(i):
q.put(i)
print("say hi", i, q.qsize()) # mac下调qsize()会报错,可以看下qsize的源码 # if __name__ == '__main__': # 在windows下运行需要加这行,否则会报错
q = queues.Queue(20, ctx=multiprocessing)
for i in range(10):
p = Process(target=foo, args=(i,))
p.start()
  • Array
from multiprocessing import Process
from multiprocessing import Array def foo(i, arg):
arg[i] = i + 100
for item in arg:
print(item)
print("==================") # if __name__ == '__main__': # windows下需要加上这行,否则会报错
li = Array('i', 10)
for i in range(10):
p = Process(target=foo, args=(i, li,))
p.start()
  • Manager
from multiprocessing import Process
from multiprocessing import Manager
import time def foo(i, arg):
arg[i] = i + 100
print(arg.values()) # if __name__ == '__main__': # windows下需要添加这行,否则会报错 obj = Manager()
li = obj.dict()
for i in range(10):
p = Process(target=foo, args=(i, li,))
p.start()
# p.join() time.sleep(0.1) # 需要加个等待时间,否则主进程执行完毕之后就会将li关闭掉, 或者在上面加个join

进程锁

参考线程锁

进程池


from multiprocessing import Pool import time def f1(arg):
time.sleep(1)
print(arg) # if __name__ == '__main__': # 在windows下执行需要加上这行,否则会报错 pool = Pool(5)
for i in range(30):
# pool.apply(func=f1, args=(i,)) # 单进程模式
pool.apply_async(func=f1, args=(i,)) # pool.close() # 所有任务执行完毕,在进行关闭进程池
pool.terminate() # 立即关闭进程池
pool.join()
print("end")

协程

原理:利用一个线程,分解一个线程成为多个微线程,程序级别,跟系统没关系
  • greenlet # 在gevent的基础之上进行的封装
  • gevent
from gevent import monkey
monkey.patch_all() import gevent
import requests def f(url):
print("GET: %s" % url)
resp = requests.get(url)
data = resp.text
print("%d bytes received from %s" % (len(data), url)) gevent.joinall([
gevent.spawn(f, "http://www.python.org"),
gevent.spawn(f, "http://www.yahoo.com"),
gevent.spawn(f, "http://www.github.com"),
])

python学习之路-11 多线程、多进程、协程的更多相关文章

  1. Python学习之路14☞多线程与多进程

    一 进程与线程的概念 1.1 进程 进程定义: 进程就是一个程序在一个数据集上的一次动态执行过程.进程一般由程序.数据集.进程控制块三部分组成.我们编写的程序用来描述进程要完成哪些功能以及如何完成:数 ...

  2. 多线程 多进程 协程 Queue(爬虫代码)

    快速理解多进程与多线程以及协程的使用场合和特点 首先我们来了解下python中的进程,线程以及协程! 从计算机硬件角度: 计算机的核心是CPU,承担了所有的计算任务.一个CPU,在一个时间切片里只能运 ...

  3. Python并发编程二(多线程、协程、IO模型)

    1.python并发编程之多线程(理论) 1.1线程概念 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程(流水线的工作需要电源,电源就相当于 ...

  4. Python学习之路11☞异常处理

    一 错误和异常 part1:程序中难免出现错误,而错误分成两种 1.语法错误(这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正) #语法错误示范一 if #语法错误示范二 de ...

  5. 深入浅析python中的多进程、多线程、协程

    深入浅析python中的多进程.多线程.协程 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源 ...

  6. Python多进程、多线程、协程

    转载:https://www.cnblogs.com/huangguifeng/p/7632799.html 首先我们来了解下python中的进程,线程以及协程! 从计算机硬件角度: 计算机的核心是C ...

  7. 也说性能测试,顺便说python的多进程+多线程、协程

    最近需要一个web系统进行接口性能测试,这里顺便说一下性能测试的步骤吧,大概如下 一.分析接口频率 根据系统的复杂程度,接口的数量有多有少,应该优先对那些频率高,数据库操作频繁的接口进行性能测试,所以 ...

  8. python 多进程,多线程,协程

    在我们实际编码中,会遇到一些并行的任务,因为单个任务无法最大限度的使用计算机资源.使用并行任务,可以提高代码效率,最大限度的发挥计算机的性能.python实现并行任务可以有多进程,多线程,协程等方式. ...

  9. python中多进程+协程的使用以及为什么要用它

    前面讲了为什么python里推荐用多进程而不是多线程,但是多进程也有其自己的限制:相比线程更加笨重.切换耗时更长,并且在python的多进程下,进程数量不推荐超过CPU核心数(一个进程只有一个GIL, ...

随机推荐

  1. Map的内容按字母顺序排序

    map有自带的排序功能,但需要重写排序方法,代码如下: package coreJava.com.shindo.corejava.map; import java.util.ArrayList; im ...

  2. (转)Building MariaDB on Mac OS X using Homebrew

    https://kb.askmonty.org/en/building-mariadb-on-mac-os-x-using-homebrew/ Work has been done to provid ...

  3. 使用面向 iOS 的本机插件扩展

    本文细致探讨了 Xcode(以 iOS 设备为目标)中的 PhoneGap(也称为 Apache Cordova)应用程序本机插件.如果您刚开始接触 PhoneGap 或者需要回顾 PhoneGap ...

  4. UVA 825 Walking on the Safe Side(记忆化搜索)

      Walking on the Safe Side  Square City is a very easy place for people to walk around. The two-way ...

  5. [华为机试练习题]55.最大公约数 & 多个数的最大公约数

    题目 描写叙述: 输入2个数字,最后输出2个数字的最大公约数 题目类别: 位运算 难度: 0基础 执行时间限制: 无限制 内存限制: 无限制 阶段: 入职前练习 输入: 2个整数 输出: 输出数字1和 ...

  6. Sass函数--列表函数

    列表函数简介 列表函数主要包括一些对列表参数的函数使用,主要包括以下几种: length($list):返回一个列表的长度值: nth($list, $n):返回一个列表中指定的某个标签值  join ...

  7. 后台js

    Response.Write("<script>alert('该用户名不存在或密码错误或未参加教学活动,请重新输入!');history.back()</script> ...

  8. Css控制div水平垂直居中显示

    <style>#info{height:0px; width:0px;top:50%; left:50%;position:absolute;}#center{background:#FF ...

  9. idea导入项目出错

    在idea导如项目后,总是会报错,每个类都会报错.解决的办法是: 1. 2.添加本地jdk 3.添加项目中的lib包

  10. tomcat 支持https

    HTTP是平时浏览网页时候使用的一种协议.HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全.为了保证 这些隐私数据能加密传输,于是网景公司设计了SSL(Se ...