Python 线程同步变量,同步条件,列队
条件变量同步
有一类线程需要满足条件之后才能够继续执行,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 线程同步变量,同步条件,列队的更多相关文章
- python线程中的同步问题
多线程开发可能遇到的问题 假设两个线程t1和t2都要对num=0进行增1运算,t1和t2都各对num修改1000000次,num的最终的结果应该为2000000.但是由于是多线程访问,有可能出现下面情 ...
- python 线程之 数据同步 Queue
Queue:将数据从一个线程发往另外一个线程比较通用的方式是使用queue模块的Queue类 1, 首先创建一个Queue模块的对象,创建Queue对象可以传递maxsize也可以不传递 2. 使用对 ...
- python初识,变量,条件判断语句,基本数据类型,while循环语句
python文件后缀可以是任意,但是导入模块时不用.py后缀时会报错 python文件的两种执行方式: python解释器 python文件路径 进入python解释权,事实获取执行结果 在Linux ...
- Python学习---线程锁/信号量/条件变量同步/线程池1221
线程锁 问题现象: 多线程情况下,CPU遇到阻塞会进行线程的切换,所以导致执行了tmp-=1的值还未赋值给num=tmp,另一个线程2又开始了tmp -=1,所以导致最后的值重复赋值给了num,所以出 ...
- 练习生产者与消费者-PYTHON多线程中的条件变量同步-Queue
以前练习过,但好久不用,手生,概念也生了, 重温一下.. URL: http://www.cnblogs.com/holbrook/tag/%E5%A4%9A%E7%BA%BF%E7%A8%8B/ ~ ...
- PYTHON线程知识再研习E---条件变量同步Condition
Python提供的Condition对象提供了对复杂线程同步问题的支持.Condition被称为条件变量,除了提供与Lock类似的 acquire和release方法外,还提供了wait和notify ...
- python多线程编程5: 条件变量同步-乾颐堂
互斥锁是最简单的线程同步机制,Python提供的Condition对象提供了对复杂线程同步问题的支持.Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还 ...
- 27 python 初学(信号量、条件变量、同步条件、队列)
参考博客: www.cnblogs.com/yuanchenqi/articles/5733873.html semaphore 信号量: condition 条件变量: event 同步条件:条件 ...
- Linux 多线程条件变量同步
条件变量是线程同步的另一种方式,实际上,条件变量是信号量的底层实现,这也就意味着,使用条件变量可以拥有更大的自由度,同时也就需要更加小心的进行同步操作.条件变量使用的条件本身是需要使用互斥量进行保护的 ...
随机推荐
- git 命令(基础篇)的本质理解
主要命令 1. 提交,git commit 本质:创建一个节点(node),标志了当前位置(node)与以前的node存在不同之处,如下图中的 c0 <-- c1 <-- c2 等等 图中 ...
- [Project] MiniSearch文本检索简介
1. 预处理过程 预处理主要用来事先生成程序在运行过程中可能用到的数据,以便加速处理时间. 预处理的过程主要生成程序所需的三个文件:网页库文件,网页位置信息文件和倒排索引文件. 网页库文件 其中网页库 ...
- Centos 执行top命令详细解读
1.作用:top命令用来显示执行中的程序进程,使用权限是所有用户. 2.格式:top [-] [d delay] [q] [c] [S] [s] [i] [n] 3.主要参数: d:指定更新的间隔,以 ...
- SQL注入的优化和绕过
作者:Arizona 原文来自:https://bbs.ichunqiu.com/thread-43169-1-1.html 0×00 ~ 介绍 SQL注入毫无疑问是最危险的Web漏洞之一,因为我们将 ...
- 使用docker redis-cluster集群搭建
参考https://www.cnblogs.com/cxbhakim/p/9151720.html此文 主要搭建过程参考上文,此处讲下主要过程和遇到的坑 首先是镜像的基础搭建,我不知道是否是作者编写时 ...
- 鱼眼投影方式(Fisheye projection)的软件实现
简单实现 鱼眼模式(Fisheye)和普通的透视投影(Perspective projection),一个很大的区别就是鱼眼的投影算法是非线性的(non-linear),实际照相机的情况是在镜头外面包 ...
- C语言中volatile的作用和使用方法
在程序设计中,尤其是在C语言.C++.C#和Java语言中,使用volatile关键字声明的变量或对象通常具有与优化.多线程相关的特殊属性. 通常,volatile关键字用来阻止(伪)编译器认为的无法 ...
- Java线程池(ThreadPoolExecutor)原理分析与使用
在我们的开发中"池"的概念并不罕见,有数据库连接池.线程池.对象池.常量池等等.下面我们主要针对线程池来一步一步揭开线程池的面纱. 使用线程池的好处 1.降低资源消耗 可以重复利用 ...
- [EXP]K8 jboss invoke deploy getshell exploit
MSF jboss invoke deploy EXPLOIT moudle Date:2013.11.28 Author:K8gege 改这个EXP中 过程有点不进人意 没能在一个payload里直 ...
- RabbitMQ常见错误2
java.io.IOException at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:105) at com.rabbitmq ...