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的时候,就阻塞在哪里).而互斥锁是用在多线程多任务互斥的,一个线程占用了某 ...
随机推荐
- Reinforcement Learning: An Introduction读书笔记(4)--动态规划
> 目 录 < Dynamic programming Policy Evaluation (Prediction) Policy Improvement Policy Iterat ...
- js之单例模式
单例模式是指一个类,只有一个实例.实现的思路是,创建实例时候加判断,如果有实例则返回,如果没有就new一个,并返回. 第一步: 创建类. function Waiter(id, name, salar ...
- es6 语法 (模块化)
//export export let A=123; //导出 //导出函数 export function test(){ console.log('test'); } //导出类 export c ...
- CSS3效果:波浪效果
实现效果 如图所示: 首先得准备三张图,一张是浅黄色的背景图loading_bg.png,一张是深红色的图loading.png,最后一张为bolang.png. css代码 body{backgro ...
- 洛谷P4593 [TJOI2018]教科书般的亵渎(拉格朗日插值)
题意 题目链接 Sol 打出暴力不难发现时间复杂度的瓶颈在于求\(\sum_{i = 1}^n i^k\) 老祖宗告诉我们,这东西是个\(k\)次多项式,插一插就行了 上面的是\(O(Tk^2)\)的 ...
- 基于timestamp和nonce的防重放攻击
以前总是通过timestamp来防止重放攻击,但是这样并不能保证每次请求都是一次性的.今天看到了一篇文章介绍的通过nonce(Number used once)来保证一次有效,感觉两者结合一下,就能达 ...
- 【代码笔记】Web-JavaScript-JavaScript 运算符
一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- Android6.0 源码修改之屏蔽导航栏虚拟按键(Home和RecentAPP)/动态显示和隐藏NavigationBar
场景分析, 为了完全实现沉浸式效果,在进入特定的app后可以将导航栏移除,当退出app后再次将导航栏恢复.(下面将采用发送广播的方式来移除和恢复导航栏) ps:不修改源码的情况下,简单的沉浸式效果实现 ...
- 生成器(generator,yield),next,send
#生成器 def generator(): for i in range(200): yield '哇哈哈%s' %i g = generator() #调用生成数函数,接受作用 ret = g.__ ...
- .NET Core 2.0
下载 Visual Studio 2017 version 15.3 下载 .NET Core 2.0 下载 Visual Studio for Mac 微软今天发布了.NET Core 2.0 版本 ...