Python:Day29 信号量、条件变量
信号量:semaphore
信号量是用来控制线程并发数的。(理解:虽然GIL任意时刻都只有一个线程被执行,但是所有线程都有资格去抢,semaphore就是用来控制抢的GIL的数量,只有获取了semaphore的线程才有资格去抢GIL,起到了限制线程并发数的作用)
import threading
import time class MyThread(threading.Thread):
def run(self):
if semap.acquire():
print(semap)
print(self.name)
time.sleep(5)
semap.release() semap = threading.Semaphore(5) # 括号内如果没有指定数据,默认为1 thrs = [] for i in range(100):
thrs.append(MyThread())
for i in thrs:
i.start()
semaphore也是一把锁,这把锁内部有一个计数器,被acquire()的时候-1,release()的时候+1,当计数器为0的时候,其它线程将被阻塞。
semaphore和RLock都可以被重复获取,也都有计数器,区别是:semaphore是被不同线程获取,而RLock只能被同一线程重复获取。
条件变量:不仅能实现锁的功能,而且能够实现类似线程间的通信功能
用于一个标志符来实现线程间通信
threading.Condition([Lock/Rlock]):锁是可选选项,不传入锁,对象自动创建一个Rlock(0
wait():条件不满足时调用,线程会释放锁并进入等待阻塞
notify():条件创造后调用,通知等待池激活一个线程
notifyAll():条件创造后调用,通知等待池激活所有线程
import threading
from random import randint
import time class Producer(threading.Thread):
def run(self):
global L
while 1:
lock_con.acquire()
r = randint(0, 100)
print(self.name + "已生产" + str(r))
L.append(r)
lock_con.notify()
lock_con.release()
time.sleep(1) class Consumer(threading.Thread):
def run(self):
global L
while 1:
lock_con.acquire()
if len(L) == 0:
lock_con.wait()
print("消费者吃了"+str(L[0]))
del L[0]
lock_con.release() if __name__ == '__main__':
L = []
lock_con = threading.Condition()
threads = []
for i in range(5):
threads.append(Producer())
threads.append(Consumer())
for i in threads:
i.start()
要想实现两个线程之间的通信,两个线程用的必须是同一把锁,不然无法起到作用。
条件同步(Event)
条件同步和条件变量同步差不多,只是少了锁的功能,因为条件同步设计于不访问共享资源的环境。
event = threading.Event():条件环境变量,初始值为False
event.isSet():返回event的状态值
event.set():设备event的状态值为True,所有阻塞池的线程激活进入就绪状态,等待操作系统调试。
event.clear():设置event的状态值为False
event.wait():如果event的状态值为False时,阻塞线程
实例1:
import threading
import time class Boss(threading.Thread):
def run(self):
print("今晚要加班!!!!")
event.set()
time.sleep(5)
print("已经10点了,可以下班了!")
event.set() class Work(threading.Thread):
def run(self):
event.wait()
print("命苦啊!!!!")
event.clear()
event.wait()
print("oh,yeah!") if __name__ == '__main__':
event = threading.Event()
threads = []
for i in range(3):
threads.append(Work())
threads.append(Boss())
for i in threads:
i.start()
for i in threads:
i.join()
实例2:红绿灯
import threading
import time
import random def ligth():
if not event.isSet():
event.set()
count = 0
while 1:
if count < 10:
print("this light is green!")
elif count < 13:
print("the light is yellow!")
elif count < 20:
if event.isSet():
event.clear()
print("the light is red!")
else:
count = 0
event.set()
time.sleep(1)
count += 1 def car(n):
while 1:
time.sleep(random.randrange(10))
if event.isSet():
print("car %s is running" % n)
else:
print("car %s is waiting for red light..." % n) event = threading.Event()
Light = threading.Thread(target=ligth)
Light.start()
for i in range(3):
t = threading.Thread(target=car,args=(i,))
t.start()
Python:Day29 信号量、条件变量的更多相关文章
- [转]一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程
一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程 希望此文能给初学多线程编程的朋友带来帮助,也希望牛人多多指出错误. 另外感谢以下链接的作者给予,给我的学习带来了很大帮助 http ...
- Python学习---线程锁/信号量/条件变量同步/线程池1221
线程锁 问题现象: 多线程情况下,CPU遇到阻塞会进行线程的切换,所以导致执行了tmp-=1的值还未赋值给num=tmp,另一个线程2又开始了tmp -=1,所以导致最后的值重复赋值给了num,所以出 ...
- python线程的条件变量Condition的用法实例
Condition 对象就是条件变量,它总是与某种锁相关联,可以是外部传入的锁或是系统默认创建的锁.当几个条件变量共享一个锁时,你就应该自己传入一个锁.这个锁不需要你操心,Condition 类会 ...
- Condition条件变量
条件变量是一种比较复杂的线程同步机制 #!/usr/bin/env python # -*- coding: utf-8 -*- """ 条件变量,线程间通信提供的另一种 ...
- 27 python 初学(信号量、条件变量、同步条件、队列)
参考博客: www.cnblogs.com/yuanchenqi/articles/5733873.html semaphore 信号量: condition 条件变量: event 同步条件:条件 ...
- [转]Posix-- 互斥锁 条件变量 信号量
这是一个关于Posix线程编程的专栏.作者在阐明概念的基础上,将向您详细讲述Posix线程库API.本文是第三篇将向您讲述线程同步. 互斥锁 尽管在Posix Thread中同样可以使用IPC的信号量 ...
- Linux同步机制(二) - 条件变量,信号量,文件锁,栅栏
1 条件变量 条件变量是一种同步机制,允许线程挂起,直到共享数据上的某些条件得到满足. 1.1 相关函数 #include <pthread.h> pthread_cond_t cond ...
- 练习生产者与消费者-PYTHON多线程中的条件变量同步-Queue
以前练习过,但好久不用,手生,概念也生了, 重温一下.. URL: http://www.cnblogs.com/holbrook/tag/%E5%A4%9A%E7%BA%BF%E7%A8%8B/ ~ ...
- 【C】——信号量 互斥锁 条件变量的区别
信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在哪里).而互斥锁是用在多线程多任务互斥的,一个线程占用了某 ...
随机推荐
- HDU 1848 Fibonacci again and again(SG函数)
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...
- SAP MM 按采购订单查询付款信息的报表?
SAP MM 按采购订单查询付款信息的报表? 上午给P3项目采购部门用户做了一个采购相关的报表的培训.培训过程中,客户的采购部门经理提出了一个问题:有没有报表能查询到各个采购订单的付款情况,显示采购订 ...
- 深度学习新星:GAN的基本原理、应用和走向
深度学习新星:GAN的基本原理.应用和走向 (本文转自雷锋网,转载已获取授权,未经允许禁止转载)原文链接:http://www.leiphone.com/news/201701/Kq6FvnjgbKK ...
- DES数据解密
/// <summary> /// DES数据解密 /// </summary> /// <param name="targetValue">& ...
- Tomcat映射虚拟路径到指定磁盘(eclipse)
用WangEditor富文本编辑,上传图片的时候,本文主要记录一下Tomcat映射虚拟路径到指定磁盘,保存到指定路径中,且能实现页面预览. 在实现之前wangeditor的简单实用请参照博主小道仙的后 ...
- MFC Bresesnham算法
Bresesnham算法绘制直线段 Bresenham算法的意义:高效的将图形光栅化.其计算过程中均采用加法运算,故大大减少了程序的开销. 绘制直线段(MFC中) //传入参数:起点.终点,颜色 vo ...
- MySQL针对对账数据,每天每个店只能产生一条对账记录,对数据库数据进行添加联合唯一索引设置
ALTER TABLE StoreDailyCheck ADD UNIQUE INDEX(StoreId,CheckDate);
- WARNING: Re-reading the partition table failed with error 22: Invalid argument
在划分磁盘分区时,遇到错误"WARNING: Re-reading the partition table failed with error 22: Invalid argument&qu ...
- C#-类(九)
类的定义 类是描述具有相同特征与行为的事物的抽象,类内部包含类的特征和类的行为 类支持继承 类的定义是关键字class为标志 类的格式 访问标识符 class 类名 { 类主体 } 访问标识符:指定了 ...
- SQL Server @@ERROR的小误区大Bug
在公司项目中看到有这样使用事务的: -- 开启事务 BEGIN TRAN ) ) BEGIN ROLLBACK TRAN END COMMIT TRAN 乍一看没啥问题,仔细思考就能发现有很大的问题. ...