信号量

信号量也是一把锁,可以指定信号量为5,对比互斥锁同一时间只能有一个任务抢到锁去执行,信号量同一时间可以有5个任务拿到锁去执行。

如果说互斥锁是合租房屋的人去抢一个厕所,那么信号量就相当于一群路人争抢公共厕所,公共厕所有多个坑位,这意味着同一时间可以有多个人上公共厕所,但公共厕所容纳的人数是一定的,这便是信号量的大小。

from threading import Thread,Semaphore,current_thread
import time,random sm = Semaphore(3) # 设置信号量为3,即同时会有3个任务会抢到锁 def task():
sm.acquire()
print("%s acquire task" %current_thread().getName())
time.sleep(random.randint(1,3))
sm.release()
print("-------- %s release task \n" % current_thread().getName()) if __name__ == '__main__':
for i in range(10):
t = Thread(target=task)
t.start() ------------输出------------
Thread-1 acquire task
Thread-2 acquire task
Thread-3 acquire task
-------- Thread-1 release task -------- Thread-3 release task
Thread-4 acquire task
Thread-5 acquire task -------- Thread-5 release task -------- Thread-2 release task Thread-7 acquire task
Thread-6 acquire task
-------- Thread-7 release task
Thread-8 acquire task -------- Thread-4 release task Thread-9 acquire task
-------- Thread-6 release task Thread-10 acquire task
-------- Thread-8 release task -------- Thread-9 release task -------- Thread-10 release task

 原理 

1. Semaphore管理一个内置的计数器
2. 每当调用acquire()时内置计数器-1
3. 调用release() 时内置计数器+1
4. 计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()

Event

线程的一个关键特性是每个线程都是独立运行且状态不可预测。如果程序中的其 他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时线程同步问题就会变得非常棘手。

为了解决这些问题,我们需要使用threading库中的Event对象。 对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生。

在 初始情况下,Event对象中的信号标志被设置为假。如果有线程等待一个Event对象, 而这个Event对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真。

一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程。如果一个线程等待一个已经被设置为真的Event对象,那么它将忽略这个事件, 继续执行

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

 例如,有多个工作线程尝试链接MySQL,我们想要在链接前确保MySQL服务正常才让那些工作线程去连接MySQL服务器,如果连接不成功,

都会去尝试重新连接。那么我们就可以采用threading.Event机制来协调各个工作线程的连接操作

from threading import currentThread, Thread,Event
import time event = Event() def conn_mysql():
"连接mysql"
count = 1
while not event.is_set():
# 当没有检测到时候
if count > 3: # 如果尝试次数大于3,就主动抛异
raise ConnectionError('尝试链接的次数过多') print('%s 第%s次尝试' % (currentThread(), count)) event.wait(timeout=1) # 等待检测(里面的参数是超时1秒) count += 1 print('%s 开始链接...' % (currentThread().getName())) def check_mysql():
''' 检测数据库'''
print('%s 检测mysql...' % (currentThread().getName()))
time.sleep(2)
event.set() if __name__ == '__main__':
for i in range(3):
t = Thread(target=conn_mysql)
t.start() t = Thread(target=check_mysql)
t.start() ----输出------
<Thread(Thread-1, started 7860)> 第1次尝试
<Thread(Thread-2, started 2816)> 第1次尝试
<Thread(Thread-3, started 8188)> 第1次尝试
Thread-4 检测mysql...
Thread-2 开始链接...
Thread-1 开始链接...
<Thread(Thread-1, started 7860)> 第2次尝试
Thread-3 开始链接...
<Thread(Thread-3, started 8188)> 第2次尝试
<Thread(Thread-2, started 2816)> 第2次尝试
Thread-1 开始链接...
Thread-3 开始链接...
Thread-2 开始链接...

  

定时器

定时器,指定n秒后执行某操作

from threading import Timer

def task(name):
print('hell0 %s' % name) t = Timer(5,task,args=('egon',))
t.start()

  

验证码输入

from threading import Timer
import random class Code(object):
def __init__(self):
self.make_cache() def make_cache(self,interval=10):
self.cache = self.make_code()
print("验证码:", self.cache)
self.t = Timer(interval, self.make_cache) # 每过5s执行一次
self.t.start() def make_code(self,n=4):
res = ''
for i in range(n):
s1 = str(random.randint(0,9))
s2 = chr(random.randint(65,90))
res += random.choice([s1,s2])
return res def check_code(self):
while True:
code = input("请输入验证码>> ").strip()
if code.upper() == self.cache:
print('验证码输入正确!')
self.t.cancel()
break
obj = Code()
obj.check_code()

  

python 信号量,Event, 定时器的更多相关文章

  1. ~~并发编程(十三):信号量,Event,定时器~~

    进击のpython ***** 并发编程--信号量,Event,定时器 本节需要了解的就是: 信号量,以及信号量和互斥锁的区别 了解时间和定时器,以及使用 信号量 信号量也是锁,本质没有变!但是他跟互 ...

  2. 11 并发编程-(线程)-信号量&Event&定时器

    1.信号量(本质也是一把锁)Semaphore模块 信号量也是一把锁,可以指定信号量为5,对比互斥锁同一时间只能有一个任务抢到锁去执行, 信号量同一时间可以有5个任务拿到锁去执行, 如果说互斥锁是合租 ...

  3. 多线程《七》信号量,Event,定时器

    一 信号量 信号量也是一把锁,可以指定信号量为5,对比互斥锁同一时间只能有一个任务抢到锁去执行,信号量同一时间可以有5个任务拿到锁去执行,如果说互斥锁是合租房屋的人去抢一个厕所,那么信号量就相当于一群 ...

  4. 并发编程---死锁||递归锁---信号量---Event事件---定时器

    死锁 互斥锁:Lock(),互斥锁只能acquire一次 递归锁:  RLock(),可以连续acquire多次,每acquire一次计数器+1,只有计数为0时,才能被抢到acquire # 死锁 f ...

  5. python从写定时器学习Thread

    目录 python从写定时器学习Thread Timer 对象 粗陋的循环定时器 更 pythonic 循环定时器 FAQ python从写定时器学习Thread python 如何写一个定时器,循环 ...

  6. 模仿linux内核定时器代码,用python语言实现定时器

    大学无聊的时候看过linux内核的定时器,如今已经想不起来了,也不知道当时有没有看懂,如今想要模仿linux内核的定时器.用python写一个定时器,已经想不起来它的设计原理了.找了一篇blog,li ...

  7. SQLServer和MySQL job和 event定时器的差别

    SQLServer和MySQL job和 event定时器的差别

  8. python并发编程-多线程实现服务端并发-GIL全局解释器锁-验证python多线程是否有用-死锁-递归锁-信号量-Event事件-线程结合队列-03

    目录 结合多线程实现服务端并发(不用socketserver模块) 服务端代码 客户端代码 CIL全局解释器锁****** 可能被问到的两个判断 与普通互斥锁的区别 验证python的多线程是否有用需 ...

  9. python网络编程--管道,信号量,Event,进程池,回调函数

    1.管道 加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行任务修改,即串行修改,速度慢了,但牺牲了速度却保证了数据安全. 文件共享数据实现进程间的通信,但问题是: 1.效率低(共享 ...

随机推荐

  1. fmt标签如何计算两个日期之间相隔的天数

    <h2>start -- ${start}</h2><h2>end -- ${end}</h2><fmt:formatDate var=" ...

  2. 2019.01.20 NOIP模拟 迅雷(kruskal/二分+并查集)

    传送门 题意简述:给一张带权无向图,有a,ba,ba,b两类特殊点和普通点,问使得至少有一个aaa和一个bbb连通所需要的所有边边权最小值的最大值是多少. 思路: 一眼发现可以二分,考虑怎么check ...

  3. 定时调度系列之Quartz.Net详解(转)

    出处:https://www.cnblogs.com/yaopengfei/p/9216229.html 一. 背景 我们在日常开发中,可能你会遇到这样的需求:"每个月的3号给用户发信息,提 ...

  4. 将批量指定的docker镜像打成文件

      #/bin/bash tag= img1=hub.chinacloud.com.cn/onex.dev/one-task-scheduler:$tag img2=hub.chinacloud.co ...

  5. yml的mybatis的sql查看;Mybatis+Springboot 控制台查看日志,Mybatis结合springboot打印日志

    1.配置如图 文件为yml mybatis: mapper-locations: classpath:com/springboot/transaction/mapper/*.xml configura ...

  6. SHELL脚本之awk妙用

    对于一个sougou文本文件,解压后大概4G,要求在其基础上切出第一列时间年月日时分秒增加在列中,作为hive的一个索引.先将文件head一下展示格式: [root@Master date]# hea ...

  7. DIV+CSS中标签ul ol li dl dt dd用法

    ul ol li dl dt dd都是DIV+CSS做网页长用的东西,相当于一棵树的树技,下面就了解一下这些东西的全体用法,本人用dd,dt,dd用得很少,懂得结合使用对做架构是很有好处的哦! DIV ...

  8. Linux下VNC配置使用总结:开启+桌面配置+安全访问

    操作环境:CentOS 5.3 + Windows XP SP3 32bit + RealVNC 4.1.2 i386 + TigerVNC. 参考:潇湘隐者-Linux系统VNC配置实践总结,萨米的 ...

  9. spring ioc beanfactory 关系图

    spring security类关系图 mybatis-spring源码解析类关系图 Spring与Mybatis整合的MapperScannerConfigurer处理过程源码分析 转: sprin ...

  10. SSM_CRUD新手练习(6)分页后台控制器编写

    经过测试基础环境已经搭建好了,现在我们开始编写CRUD. 我们来看一下查询的逻辑该怎么写: 1.访问index.jsp页面 2.index.jsp页面发送查询员工的请求 3.EmployeeContr ...