1、信号量(本质也是一把锁)Semaphore模块

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

信号量同一时间可以有5个任务拿到锁去执行,

如果说互斥锁是合租房屋的人去抢一个厕所,那么信号量就相当于一群路人争抢公共厕所,公共厕所有多个坑位,

这意味着同一时间可以有多个人上公共厕所,但公共厕所容纳的人数是一定的,这便是信号量的大小

from threading import Thread,Semaphore,currentThread
import time,random def task():
with sm:
print(f"{currentThread().getName()} in")
time.sleep(random.randint(1,3)) if __name__ == '__main__':
sm = Semaphore(3)
for i in range(10):
t = Thread(target=task)
t.start()
解析:
Semaphore管理一个内置的计数器,
每当调用acquire()时内置计数器
-1;
调用release() 时内置计数器+1;
计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。

2、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():恢复event的状态值为False。


from threading import Thread,Event,currentThread
import time
def conn():
n=0
while not event.is_set(): # while not Flase
if n == 3:
print(f"{currentThread().getName()} try too many times")
return
print(f"{currentThread().getName()} try {n}")
event.wait(0.5)
n += 1
print(f"{currentThread().getName()} is connected")
def check():
print(f"{currentThread().getName()} is connected")
time.sleep(5) # sleep(5)时间超过了wait(0.5)的时间
event.set() # 设置event的状态为True, if __name__ == '__main__':
event = Event()
for i in range(3):
t = Thread(target=conn)
t.start()
t2 = Thread(target=check)
t2.start()

Thread-1 try 0
Thread-2 try 0
Thread-3 try 0
Thread-4 is connected # 程序中是sleep(5)才 event.set()
Thread-1 try 1
Thread-2 try 1
Thread-3 try 1
Thread-2 try 2
Thread-3 try 2
Thread-1 try 2
Thread-2 try too many times
Thread-1 try too many times
Thread-3 try too many times

3、定时器

3.1、简单版本:

from threading import Timer
def hello():
print('hello word')
t = Timer(1,hello)
t.start()

3.2、每个一定时间发送验证码

import string,random
from threading import Timer
class code:
def __init__(self):
self.make_cache() def make_cache(self,interval=20):
# interval 时间间隔 每个秒自动发送新的验证码
self.cache = self.make_code
print(self.cache)
self.t = Timer(interval,self.make_cache)
self.t.start() def check(self):
while True:
msg = input('请输入你的验证码>>').strip()
if msg == self.cache:
print('True')
self.t.cancel()
break @property
def make_code(self):
s = ''.join(random.sample(string.ascii_letters + string.digits, 3))
ran1 = random.randint(0,9) # randint()头尾都包括
ran2 = chr(random.randint(65,90))# 大写
ran3 = chr(random.randint(97,122))# 小写
res =''.join([str(ran1),str(ran2),str(ran3)])
res = ''.join([res,s]) # join是把序列转化为 字符串
return res
if __name__ == '__main__':
obj = code()
obj.check()

6Mr9iX
请输入你的验证码>>6Mr9iX
True

11 并发编程-(线程)-信号量&Event&定时器的更多相关文章

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

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

  2. Python并发编程-线程同步(线程安全)

    Python并发编程-线程同步(线程安全) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 线程同步,线程间协调,通过某种技术,让一个线程访问某些数据时,其它线程不能访问这些数据,直 ...

  3. C++11 并发编程库

    C++11 并发编程 C++11 新标准中引入了几个头文件来支持多线程编程,他们分别是: <atomic>:该头文主要声明了两个类, std::atomic 和 std::atomic_f ...

  4. Java 并发编程 | 线程池详解

    原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...

  5. java并发编程 线程基础

    java并发编程 线程基础 1. java中的多线程 java是天生多线程的,可以通过启动一个main方法,查看main方法启动的同时有多少线程同时启动 public class OnlyMain { ...

  6. Python并发编程-线程

    Python作为一种解释型语言,由于使用了全局解释锁(GIL)的原因,其代码不能同时在多核CPU上并发的运行.这也导致在Python中使用多线程编程并不能实现并发,我们得使用其他的方法在Python中 ...

  7. 并发编程-线程池&J.U.C

    8. 共享模型之工具 8.1 线程池 池化技术相比大家已经屡见不鲜了,线程池.数据库连接池.Http 连接池等等都是对这个思想的应用.池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率 ...

  8. Java并发编程:线程间通信wait、notify

    Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...

  9. Java并发编程:线程和进程的创建(转)

    Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...

随机推荐

  1. PHP中数组的各种用法

    $a = 'false';if($a){ echo '好坑';}输出好坑,得转换成布尔值才行哦. in_array $people = array("Bill", "St ...

  2. 环境搭建之JAVA项目部署步骤

    一.配置java环境 1.linux下安装jdk,在此处安装1.7_x64的jdk,解压缩  tar -zxvf xxxxxxx 2.将jdk移动到/usr下 mv java /user/ 3.配置环 ...

  3. dongle0

    *CLI> -- [dongle0] Trying to connect on /dev/ttyUSB2... 插拔dongle[Jan 13 23:42:20] WARNING[3443]: ...

  4. hadoop大数据处理平台与案例

    大数据可以说是从搜索引擎诞生之处就有了,我们熟悉的搜索引擎,如百度搜索引擎.360搜索引擎等可以说是大数据技处理技术的最早的也是比较基础的一种应用.大概在2015年大数据都还不是非常火爆,2015年可 ...

  5. ubuntu 安装时分辨率太小 导致无法继续安装

    当分辨率是800 *600时,底部的按钮无法显示,不能继续安装. 可以在右上角,点击电源按钮,在系统设置中调整显示的分辨率后,继续安装.

  6. 《Wrox.Professional.Hadoop.Solutions》中文目录全稿

    前言:最近有朋友给推荐一本书,英文原版<Wrox.Professional.Hadoop.Solutions>,感觉很好打算翻译成中文,共享给朋友,时间关系,不知能否成行,先干着吧.以下部 ...

  7. VM虚拟机占内存非常大

    我发现每次打开虚拟机占用内存非常大,经常会卡死,后来上网找原因,发现内存设置的问题,所以我就修改了虚拟机的内存,网上说如果是win7,内存设置需要1-2G,如果是xp,512M就够了. 经测试,内存还 ...

  8. 上Google Adsense个人的一点体验

    最近我想开通一个Google Adsense帐号,因为以前注册过一个Google帐号,所以我以为两个是可以共通的,因为很久没上Google帐号,我记不太清密码了,所以我先是登录了Google,登上去了 ...

  9. [UE4]运行时创建Actor

  10. [UE4]使机器人受伤