条件变量同步

有一类线程需要满足条件之后才能够继续执行,Python提供了threading.Condition 对象用于条件变量线程的支持,它除了能提供RLock()或Lock()的方法外,还提供了 wait()、notify()、notifyAll()方法。

lock_con=threading.Condition([Lock/Rlock]): 锁是可选选项,不传人锁,对象自动创建一个RLock()。

wait():条件不满足时调用,线程会释放锁并进入等待阻塞;
notify():条件创造后调用,通知等待池激活一个线程;
notifyAll():条件创造后调用,通知等待池激活所有线程。
import threading, time
from random import randint class Producer(threading.Thread):
def run(self):
global L
while True:
val = randint(0, 100)
print('生产者', self.name, ':Append'+str(val),L)
if lock_con.acquire():
L.append(val)
lock_con.notify()
lock_con.release()
time.sleep(3) class Consumer(threading.Thread):
def run(self):
global L
while True:
lock_con.acquire()
if len(L) == 0:
lock_con.wait()
print('消费者', self.name, ":Delete" + str(L[0]), L)
del L[0]
lock_con.release()
time.sleep(0.25) if __name__ == "__main__":
L = []
lock_con = threading.Condition()
threads = []
for i in range(5):
threads.append(Producer())
threads.append(Consumer())
for t in threads:
t.start()
for t in threads:
t.join()
print('---- end ----') #运行结果:
生产者 Thread-1 :Append63 []
生产者 Thread-2 :Append66 [63]
生产者 Thread-3 :Append20 [63, 66]
生产者 Thread-4 :Append83 [63, 66, 20]
生产者 Thread-5 :Append2 [63, 66, 20, 83]
生产者 Thread-4 :Append26 []
消费者 Thread-6 :Delete26 [26]
生产者 Thread-2 :Append21 []
生产者 Thread-3 :Append71 [21]
生产者 Thread-1 :Append19 [21, 71]
生产者 Thread-5 :Append100 [21, 71, 19]
生产者 Thread-1 :Append96 []
消费者 Thread-6 :Delete96 [96]
........

同步条件

条件同步和条件变量同步差不多意思,只是少了锁功能,因为条件同步设计于不访问共享资源的条件环境。event=threading.Event():条件环境对象,初始值 为False;

event.isSet():返回event的状态值;
event.wait():如果 event.isSet()==False将阻塞线程;
event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
event.clear():恢复event的状态值为False。
import threading, time

class Boss(threading.Thread):
def run(self):
print("BOSS: 今晚大家加班")
event.isSet() or event.set()
time.sleep(5)
print("BOSS: 大家可以下班了")
event.isSet() or event.set() class Worker(threading.Thread):
def run(self):
event.wait()
print("Worker: 唉。。。。")
time.sleep(0.25)
event.clear()
event.wait()
print("Worker: Great!") if __name__ == "__main__":
event = threading.Event()
threads = []
for i in range(5):
threads.append(Worker())
threads.append(Boss())
for t in threads:
t.start()
for t in threads:
t.join() #运行结果:
BOSS: 今晚大家加班
Worker: 唉。。。。
Worker: 唉。。。。
Worker: 唉。。。。
Worker: 唉。。。。
Worker: 唉。。。。
BOSS: 大家可以下班了
Worker: Great!
Worker: Great!
Worker: Great!
Worker: Great!
Worker: Great!

列队

q = Queue.Queue(maxsize = 10) 创建一个“队列”对象。Queue.Queue类即是一个队列的同步实现。队列长度可为无限或者有限。可通过Queue的构造函数的可选参数maxsize来设定队列长度。如果maxsize小于1就表示队列长度无限。

q.put()方法在队尾插入一个项目。put()有两个参数,第一个item为必需的,为插入项目的值;第二个block为可选参数,默认为1。如果队列当前为空且block为1,put()方法就使调用线程暂停,直到空出一个数据单元。如果block为0,put方法将引发Full异常。

q.get([block[, timeout]])方法从队头删除并返回一个项目。可选参数为block,默认为True。如果队列为空且block为True,get()就使调用线程暂停,直至有项目可用。如果队列为空且block为False,队列将引发Empty异常,timeout等待时间。

q.qsize() 返回队列的大小
q.empty() 如果队列为空,返回True,反之False
q.full() 如果队列满了,返回True,反之False
q.full 与 maxsize 大小对应
q.get_nowait() 相当q.get(False)
q.put_nowait(item) 相当q.put(item, False)
q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号
q.join() 实际上意味着等到队列为空,再执行别的操作
import queue

d = queue.Queue()

d.put('1')
d.put('2')
d.put('3') print(d.get())
print(d.get())
print(d.get())
print(d.get())
print(d.get(0)) # 运行结果:
1
2
3
报错:
queue.Empty

线程操作列表是不安全的。

import threading, time

li = [1, 2, 3, 4, 5]

def pri():
while li:
a = li [-1]
print(a)
time.sleep(1)
try:
li.remove(a)
except:
print('-----', a)
t1 = threading.Thread(target=pri, args=())
t1.start()
t2 = threading.Thread(target=pri, args=())
t2.start() # 运行结果:
5
5
4
----- 5
4
3
----- 4
3
2
----- 3
2
1
----- 2
1
----- 1
import threading, queue
from time import sleep
from random import randint class Production(threading.Thread):
def run(self):
while True:
r = randint(0, 100)
q.put(r)
print("生产出来 %s 号包子" %r)
sleep(1) class Proces(threading.Thread):
def run(self):
while True:
re = q.get()
print('吃掉 %s号包子' %re) if __name__ == '__main__':
q = queue.Queue(10)
threads = [Production(),Production(),Production(),Proces()]
for t in threads:
t.start() # 运行结果:
生产出来 94 号包子
生产出来 13 号包子
生产出来 79 号包子
吃掉 94号包子
吃掉 13号包子
吃掉 79号包子
生产出来 43 号包子
吃掉 43号包子
生产出来 32 号包子
吃掉 32号包子
......

Python 线程同步变量,同步条件,列队的更多相关文章

  1. python线程中的同步问题

    多线程开发可能遇到的问题 假设两个线程t1和t2都要对num=0进行增1运算,t1和t2都各对num修改1000000次,num的最终的结果应该为2000000.但是由于是多线程访问,有可能出现下面情 ...

  2. python 线程之 数据同步 Queue

    Queue:将数据从一个线程发往另外一个线程比较通用的方式是使用queue模块的Queue类 1, 首先创建一个Queue模块的对象,创建Queue对象可以传递maxsize也可以不传递 2. 使用对 ...

  3. python初识,变量,条件判断语句,基本数据类型,while循环语句

    python文件后缀可以是任意,但是导入模块时不用.py后缀时会报错 python文件的两种执行方式: python解释器 python文件路径 进入python解释权,事实获取执行结果 在Linux ...

  4. Python学习---线程锁/信号量/条件变量同步/线程池1221

    线程锁 问题现象: 多线程情况下,CPU遇到阻塞会进行线程的切换,所以导致执行了tmp-=1的值还未赋值给num=tmp,另一个线程2又开始了tmp -=1,所以导致最后的值重复赋值给了num,所以出 ...

  5. 练习生产者与消费者-PYTHON多线程中的条件变量同步-Queue

    以前练习过,但好久不用,手生,概念也生了, 重温一下.. URL: http://www.cnblogs.com/holbrook/tag/%E5%A4%9A%E7%BA%BF%E7%A8%8B/ ~ ...

  6. PYTHON线程知识再研习E---条件变量同步Condition

    Python提供的Condition对象提供了对复杂线程同步问题的支持.Condition被称为条件变量,除了提供与Lock类似的 acquire和release方法外,还提供了wait和notify ...

  7. python多线程编程5: 条件变量同步-乾颐堂

    互斥锁是最简单的线程同步机制,Python提供的Condition对象提供了对复杂线程同步问题的支持.Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还 ...

  8. 27 python 初学(信号量、条件变量、同步条件、队列)

    参考博客: www.cnblogs.com/yuanchenqi/articles/5733873.html  semaphore 信号量: condition 条件变量: event 同步条件:条件 ...

  9. Linux 多线程条件变量同步

    条件变量是线程同步的另一种方式,实际上,条件变量是信号量的底层实现,这也就意味着,使用条件变量可以拥有更大的自由度,同时也就需要更加小心的进行同步操作.条件变量使用的条件本身是需要使用互斥量进行保护的 ...

随机推荐

  1. 2018.09.22 上海大学技术分享 - An Introduction To Go Programming Language

    老实说笔者学习 Go 的时间并不长,积淀也不深厚,这次因缘巧合,同组的同事以前是上海大学的开源社区推动者之一,同时我们也抱着部分宣传公司和技术分享的意图,更进一步的,也是对所学做一个总结,所以拟定了这 ...

  2. ubuntu16.04下idea、webstorm等开发工具不能输入中文问题

    问题: ubuntu16.04下idea.webstorm开发工具不能输入中文,就算切换到中文输入法输入的也是英文字母. 解决方案: 1.vim打开开发工具的启动文件(idea下就是idea.sh) ...

  3. WebService接口定义及调用

    Web service是一个平台独立的,松耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML标准来描述.发布.发现.协调和配置这些应用程序,用于开发分布式的互操作的应用程序. WebS ...

  4. word文档的python解析

    主要两块,第一个是文件类型的转换,第二个是用docx包去对word文档中的table进行parse 1. 文件格式装换 因为很多各种各样的原因,至今还有一些word文档是doc的格式存的,对于这种,如 ...

  5. PICE(4):MongoDBStreaming - gRPC Protobuf conversion

    前两篇我们介绍了JDBC和Cassandra的gRPC streaming实现.相对MongoDB来说,JDBC和Cassandra支持字符类型的query语句SQL,CQL,所以把query指令转换 ...

  6. Tomcat 部署 Web 项目的本质理解

    手动创建Web项目 不借助集成开发工具IDE,直接手动创建一个Web项目,有助于理解Web项目的本质. 1.首先建立一个myweb文件夹(自己定义项目名). 2.然后可以建一个html文件(文件里面只 ...

  7. 菜鸟在ubuntu 16.04下制作am335x的SD卡启动盘反思

    以前只在消费电子平台android和rtos上做软件,每次都是公司的环境现成的,根本不用去想启动加载那部分 的事情,最近在做一个工控机的项目时,接触到了TI的arm335x系列的平台,才发现在嵌入式的 ...

  8. [原]Windows Azure开发之Linux虚拟机

      Windows Azure是微软的云服务集合,用来提供云在线服务所需要的操作系统与基础存储与管理的平台,是微软的云计算的核心组成组件之一.其中windows azure提供的最重要的一项服务就是虚 ...

  9. Liferay7 BPM门户开发之19: 理解Service Builder体系

    Service Builder是Liferay为业务开发而设计的模型驱动(model-driven)平台工具,提供一系列的实体类.数据持久化.服务相关的代码自动生成服务.支持Hibernate and ...

  10. [Leetcode]双项队列解决滑动窗口最大值难题

    这道题是从优先队列的难题里面找到的一个题目.可是解法并不是优先队列,而是双项队列deque 其实只要知道思路,这一道题直接写没有太大的问题.我们看看题 给定一个数组 nums,有一个大小为 k 的滑动 ...