信号量: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 信号量、条件变量的更多相关文章

  1. [转]一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程

    一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程 希望此文能给初学多线程编程的朋友带来帮助,也希望牛人多多指出错误. 另外感谢以下链接的作者给予,给我的学习带来了很大帮助 http ...

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

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

  3. python线程的条件变量Condition的用法实例

      Condition 对象就是条件变量,它总是与某种锁相关联,可以是外部传入的锁或是系统默认创建的锁.当几个条件变量共享一个锁时,你就应该自己传入一个锁.这个锁不需要你操心,Condition 类会 ...

  4. Condition条件变量

    条件变量是一种比较复杂的线程同步机制 #!/usr/bin/env python # -*- coding: utf-8 -*- """ 条件变量,线程间通信提供的另一种 ...

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

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

  6. [转]Posix-- 互斥锁 条件变量 信号量

    这是一个关于Posix线程编程的专栏.作者在阐明概念的基础上,将向您详细讲述Posix线程库API.本文是第三篇将向您讲述线程同步. 互斥锁 尽管在Posix Thread中同样可以使用IPC的信号量 ...

  7. Linux同步机制(二) - 条件变量,信号量,文件锁,栅栏

    1 条件变量 条件变量是一种同步机制,允许线程挂起,直到共享数据上的某些条件得到满足. 1.1 相关函数 #include <pthread.h>  pthread_cond_t cond ...

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

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

  9. 【C】——信号量 互斥锁 条件变量的区别

    信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在哪里).而互斥锁是用在多线程多任务互斥的,一个线程占用了某 ...

随机推荐

  1. Java并发编程-CountDownLatch

    基于AQS的前世今生,来学习并发工具类CountDownLatch.本文将从CountDownLatch的应用场景.源码原理解析来学习这个并发工具类. 1. 应用场景 CountDownLatch是并 ...

  2. 构造方法为private与类修饰符为final

    构造方法为private的:在这个类外1:不能继承这个类2:不能用new来产生这个类的实例 在这个类内:1:可以继承这个类2:可以用new来产生这个类的实例 类修饰符为final的:在这个类外1:不能 ...

  3. SQLite: sql script demo

    如果有成熟的架构,如何根据数据库关系的表.视图等,进行代码生成架构?减少写代码的时间? -- 考虑主键外键 -- create database geovindu; use geovindu; --2 ...

  4. input的type类型

    对部分生僻的input属性值解释: type="reset": 可以一键清空form表单里面所有的数据 <form> <input type="text ...

  5. 中国 AI 天才养成计划:清华姚班和 100 个「张小龙」

    https://daily.zhihu.com/story/9653612?from=timeline&isappinstalled=0   AI财经社,专注未来,以及更好的生活 真正的 AI ...

  6. win10怎么录制电脑屏幕 电脑播放视频录制

    随着社会的发展,网络信息化时代已经来临,作为一个上班族,每天都离不开电脑,电脑仿佛就是我们的合作伙伴,也是陪伴我们的朋友,如今win10系统已经出来了,关于win10系统的问题相信大家有很多的问题,今 ...

  7. Android项目实战(四十二):启动页优化,去除短暂白屏或黑屏

    大家会发现一个空项目,从手机桌面打开app是秒启动.但是对于自己开发的项目,有时会发现打开app的时候,会有短暂的1秒--2秒的白屏或者黑屏,然后才进入到程序界面. 个人理解为我们自己实现的Appli ...

  8. Kotlin入门(23)适配器的进阶表达

    前面在介绍列表视图和网格视图时,它们的适配器代码都存在视图持有者ViewHolder,因为Android对列表类视图提供了回收机制,如果某些列表项在屏幕上看不到了,则系统会自动回收相应的视图对象.随着 ...

  9. UVA 1152 4 Values whose Sum is 0 (枚举+中途相遇法)(+Java版)(Java手撕快排+二分)

    4 Values whose Sum is 0 题目链接:https://cn.vjudge.net/problem/UVA-1152 ——每天在线,欢迎留言谈论. 题目大意: 给定4个n(1< ...

  10. g4e基础篇#4 了解Git存储库(Repo)

    章节目录 前言 1. 基础篇: 为什么要使用版本控制系统 Git 分布式版本控制系统的优势 Git 安装和设置 了解Git存储库(Repo) 起步 1 – 创建分支和保存代码 起步 2 – 了解Git ...