队列:queue

queue is especially useful in threaded programming when information must be exchanged safely between multiple threads.

有三种队列模式

  • class queue.Queue(maxsize=0) #先入先出
  • class queue.LifoQueue(maxsize=0) #last in fisrt out 
  • class queue.PriorityQueue(maxsize=0) #存储数据时可设置优先级的队列

用法

>>> import queue
>>> q=queue.Queue(maxsize=0) #如果maxsize小于0或者等于0表示队列无穷大
>>> q.qsize()
0
>>> q.put("")
>>> q.qsize() #获得几个槽被占用了
1
>>> q.full() #如果队列的槽没有可利用的,则返回True
False
>>> q.empty()
False
>>> q.get() # 将queue中的item取出来
''
>>> q.empty() #如果队列的槽里没有item,则返回True
True
>>>

q.put(block=False) 相当于q.put_nowait()

q.get(block=False) 相当于q.get_nowait()

q.join()

Blocks until all items in the queue have been gotten and processed

q.task_done()

Indicate that a formerly enqueued task is complete. Used by queue consumer threads.

消费者生产者模式

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。

为什么要使用生产者和消费者模式

在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

什么是生产者消费者模式

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

import queue
import threading
q=queue.Queue(maxsize =0) #maxsize设置这个队列一共有无穷大
def producer():
for i in range(10):
q.put("骨头%s" %i) #put后面可以接收很多基本的数据类型
print("开始等待所有的骨头被领走")
q.join() #阻塞,当get任务全部被完成后才执行join后面的语句
print("骨头被领完了")
def consumer(name):
while not q.empty(): #如果槽里有东西
print("%s 吃了%s" %(name,q.get()))
q.task_done()#告知任务完成,每一个get后面都需要加一个这个,如果程序里有join
t= threading.Thread(target=producer) #获得一个线程对象
t.start() #启动线程
consumer('egon')

吃包子的例子

import random,queue,threading
import time
q=queue.Queue()
def producer(name):
count = 0
while count < 20:
if q.qsize() < 8:
time.sleep(random.randrange(2))
q.put(count)
print("%s have make %s baozi" %(name,count))
else:
print("baozi remain more than 8")
count+=1
def consumer(name):
count =0
while count < 8:
time.sleep(random.randrange(3))
if not q.empty():
data = q.get()
time.sleep(0.5)
print('\033[32;1mConsumer %s has eat %s baozi...\033[0m' % (name, data))
else:
print("no more baozi to eat")
count+=1
t1=threading.Thread(target=producer,args=("lidachu1",))
t2=threading.Thread(target=producer,args=("lidachu2",))
c1=threading.Thread(target=consumer,args=("yuyang",))
c2=threading.Thread(target=consumer,args=("xiaowang",))
c3=threading.Thread(target=consumer,args=("shuaibai",))
t1.start()
t2.start()
c1.start()
c2.start()
c3.start()
t1.join()
t2.join()
c1.join()
c2.join()
c3.join()
print(q.qsize())

多进程multiprocess

multiprocessing is a package that supports spawning processes using an API similar to the threading module. The multiprocessing package offers both local and remote concurrency, effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads. Due to this, the multiprocessing module allows the programmer to fully leverage multiple processors on a given machine. It runs on both Unix and Windows.

multiprocess 是一个能支持产生多个进程的包,使用一个与threading模块类似的API(application programming interface)接口。这个multiprocessing 包能够提供本地和远程的并发(并行)),有效的回避全局解释器锁通过使用子进程而不是线程。由于这个,这个multiprocessing 模块允许程序员充分利用给定机器上的多个处理器。它可以运行在UNIX和WIndows上。

multiprocess模块与threading模块的用法类似

import time
import multiprocessing
def add():
sum = 1
for i in range(2,100000):
sum*=i
print("sum:",sum)
def multi():
count = 2
for i in range(21):
count=count**2
print("count:",count)
# s=time.time()
# add()
# multi()
# print(time.time()-s)
if __name__ == '__main__':
p1=multiprocessing.Process(target=add)
p2=multiprocessing.Process(target=multi)
s=time.time()
p1.start()
p2.start()
p1.join()
p2.join()
print(time.time()-s)

如果使用顺序执行这两个函数所需要的时间大致是20秒左右,如果使用多进程需要的时间是不到12秒。可以看出多进程的优势,前提是这两个函数的运行时间都差不多相同。

event事件

event=threading.Event()   用来进行两个或多个线程之间的交互

官方链接:   https://docs.python.org/2/library/threading.html#event-objects

This is one of the simplest mechanisms for communication between threads: one thread signals an event and other threads wait for it.

线程之间一种最简单的交流机制是:一个线程指示一个事件,并且其他线程等待它。

An event is a simple synchronization object;                event是一个简单的同步对象

the event represents an internal flag, and threads    event代表了内部的标志位和线程
can wait for the flag to be set, or set or clear the flag themselves.   能等待标志位被设置或者清除这个flag

event = threading.Event()

# a client thread can wait for the flag to be set
event.wait()

# a server thread can set or reset it

If the flag is set, the wait method doesn’t do anything.    如果flag被设置,wait方法不会起任何作用
If the flag is cleared, wait will block until it becomes set again.  如果flag为FALSE,wait方法会阻塞,直到flag设置为True。
Any number of threads may wait for the same event   任何数量的线程可能等待这相同的event

在初始化时,默认的标志位为False,

event.set()  # 将flag设置为True

event.clear()   #将flag设置为False

event.is_set()   #返回一个bool 值,判断标志位的状态

event.wait()

If the internal flag is true on entry, return immediately. Otherwise, block until another thread calls set() to set the flag to true, or until the optional timeout occurs.

#会一直阻塞直到内部的flag 为True,如果内部的标志位在入口时是True,会立刻返回,否则,会一直阻塞,直到另一个线程调用set()方法,设置flag 为True,或者知道可选的超时时间发生。

import threading
import time,random
event=threading.Event()
def foo():
event.wait()
time.sleep(1)
print("first>>>")
def bar():
sum = 0
for i in range (10):
sum+=i
print(sum)
event.set()
t1=threading.Thread(target=foo)
t2=threading.Thread(target=bar)
t1.start()
t2.start()

红绿灯

# 2、设计一个关于红绿灯的线程,5个关于车的线程;
#
# 对于车线程,每隔一个随机秒数,判断红绿灯的状态,是红灯或者黄灯,打印waiting;是绿灯打印running。
#
# 对于红绿灯线程:
# 首先默认是绿灯,做一个计数器,十秒前,每隔一秒打印“light green”;第十秒到第十三秒,每隔一秒打印“light yellow”,13秒到20秒,
# ‘light red’,20秒以后计数器清零。重新循环。
#
# 知识点:event对象(提示:event对象即红绿灯,为true是即绿灯,false时为黄灯或者红
import threading
import time,random
def car(name):
while True:
time.sleep(random.randrange(20))
if event.is_set():
print('\033[41;1m--%s running---\033[0m' %name)
elif not event.is_set():
print('\033[45;1m--%s waiting---\033[0m' %name)
def light():
count = 0
event.set()
while True:
if count < 10:
print("----light green----")
time.sleep(1)
count+=1
elif count >= 10 and count < 13:
event.clear()
print("----light yellow----")
time.sleep(1)
count+=1
elif count >= 13 and count < 20:
print("----light red----")
time.sleep(1)
count+=1
elif count == 20:
count =0
event.set() if __name__ == "__main__":
event=threading.Event()
t_light=threading.Thread(target=light)
t_light.start()
for i in range(5):
t_car=threading.Thread(target=car,args=("car%s" %i,))
t_car.start()

主线程  子线程,守护线程

1、当主线程一结束、(非守护线程的)子线程不会立即结束。
2、当主线程一结束,(守护线程的)子线程会立即结束。
3、子线程对象,在调用start()方法之前,通过调用setDaemon(true),将本子线程设置为守护线程。
 
 

队列,event,multiprocess的更多相关文章

  1. Python--day38---进程间通信--初识队列(multiprocess.Queue)

    初识队列: 进程间通信IPC(Inter-Process Communication) 1,队列的方法: q = Queue(5)1,q.put(1) #把1放进队列 2,print(q.full() ...

  2. Python--day38---进程间通信--初识队列(multiprocess.Queue)之生产者,消费者模型

    1,生产者消费者模型.py import random import time from multiprocessing import Queue, Process def producer(name ...

  3. 异步、+回调机制、线程queue、线程Event、协程、单线程实现遇到IO切换

    # from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor # import requests # import o ...

  4. python_11(网络编程)

    第1章 ucp协议 1.1 特性 1.2 缺陷 1.3 UDP协议实时通信 第2章 socket的更多方法 2.1 面向锁的套接字方法 2.1.1 blocking设置非阻塞 2.1.2 Blocki ...

  5. Python之进程 进阶 下

    在python程序中的进程操作 之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起 ...

  6. 进程、线程、协程的基本解析(python代码)

    进程什么是进程?程序就是一堆放在磁盘上的代码,进程是一段程序的运行过程正规点说,进程一般由程序.数据集.进程控制块三部分组成 什么进程切换?进程切换是,一个正在运行的进程被中断,操作系统指定另一个进程 ...

  7. WeText项目:一个基于.NET实现的DDD、CQRS与微服务架构的演示案例

    最近出于工作需要,了解了一下微服务架构(Microservice Architecture,MSA).我经过两周业余时间的努力,凭着自己对微服务架构的理解,从无到有,基于.NET打造了一个演示微服务架 ...

  8. Python:进程

    由于GIL的存在,python一个进程同时只能执行一个线程.因此在python开发时,计算密集型的程序常用多进程,IO密集型的使用多线程 1.多进程创建: #创建方法1:将要执行的方法作为参数传给Pr ...

  9. 你真的了解setTimeout和setInterval吗?

    博客园的代码排版真难用,编辑时候是好的,一保存就是乱了——本文也同时发表在我另一独立博客上 你真的了解setTimeout和setInterval吗?,可以移步至这里吧 setTimeout和setI ...

随机推荐

  1. python service 服务没有及时响应启动或控制请求

    1053错误 代码运行没有问题后,安装服务,然而start 的时候出现错误 1053:服务没有及时响应启动或控制请求(Error 1053: The service did not respond t ...

  2. jquery-numberformatter插件

    项目地址:https://code.google.com/p/jquery-numberformatter/ 非jquery版:https://github.com/andrewgp/jsNumber ...

  3. 解决亚马逊云服务器上安装nginx后无法访问的问题

    在亚马逊云服务器上装了Ubuntu系统,使用docker环境搭建nginx,启动nginx容器后,在浏览器输入地址后,显示连接超时. 在网上查了一下说有可能是服务器安全组的设置问题 然后在云服务器的安 ...

  4. Java实现小学四则运算练习

     Github项目地址:https://github.com/feser-xuan/Arithmetic.git 1.需求分析 软件基本功能要求如下: 程序可接收一个输入参数n,然后随机产生n道加减乘 ...

  5. ubuntu下安装lamp环境

    使用普通用户来安装lamp环境: 1.安装apache: sudo apt-get install apache2

  6. jQuery 版本选择与常见插件库总结

    在日常的开发中jQuery作为一个流行多年的轻量级 JavaScript 库,使用十分的普遍,主要源于它的便捷性和实用性非常高. 在此总结一些关于jQuery版本的区别和选择的建议,以及一些常见插件库 ...

  7. 2013南京网赛1003 hdu 4750 Count The Pairs

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4750 题意:给出一个无向图,f(a,b)表示从点a到点b的所有路径中的每条路径的最长边中的最小值,给出 ...

  8. iframe & cors

    iframe & cors <!DOCTYPE html> <html lang="zh-Hans"> <head> <meta ...

  9. delphi adoquery的post和UpdateBatch

    delphi adoquery的post和UpdateBatch Post是确认当前的修改,而UpdateBatch是把已经确认但是没有存盘的数据写入数据库当ADOQuery的CursorType是c ...

  10. SPOJ_VLATTICE

    题目是给你一个空间,和一个点(n,n,n),求从原点出发能够直接接触多少个点(不经过任何一个点)? 典型的mobius反演即可. 首先,ans=3,因为(1,0,0),(0,1,0),(0,0,1)这 ...