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. Selenium(ThoughtWorks公司开发的web自动化测试工具)

    Selenium也是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7.8.9).Mozilla Firefox.Mozill ...

  2. 将svnserve部署为后台服务

    由于svnserve运行模式没有部署为后台服务,很容易被人误关掉.于是在网上查了一下,发现也已经有人总结了.Copy过来,以作备忘. 以前的svnserve要想成为windows服务,必须依赖于svn ...

  3. mime type 类型名字应该用多长的字段?

    在使用 FastAdmin 时有 mimetype 字段使用了 50 长度,有小伙伴反应,不够. 在 Linux 服务器上时 xlsx 文件的 mimetype  是 application/vnd. ...

  4. BLE 4.1 和 BLE 4.2

    BLE 4.2 比 BLE4.1 多了一些新的特性. Low-power IP (IPv6/6LoWPAN) Bluetooth Smart Internet Gateways (GATT) http ...

  5. FineUI与百度地图简单示例 (转帖)

    http://www.fineui.com/bbs/forum.php?mod=viewthread&tid=4191&extra=page%3D1 前台代码 <%@ Page ...

  6. Dynamics CRM 2011 怎么根据记录的etc参数值找到实体英文名和根据etc参数值或英文名称找到其实体中文名称

    一.平常我们可以打开CRM2011一条已创建的记录,通过JScript方法获取实体英文名的方法是:按F12,输入contentIFrame.Xrm.Page.data.entity.getEntity ...

  7. R(8): tidyr

    tidy(整洁),Tidyr包是由Hadely Wickham创建,这个包提高了整理原始数据的效率,tidyr包的4个常用的函数及其用途如下: gather()——它把多列放在一起,然后转化为key: ...

  8. 关于 eclipse startexplorer插件 快速打开文件夹

    转自:http://basti1302.github.io/startexplorer/ Just drag-and-drop the button to the Eclipse menu bar t ...

  9. Nginx+tomcat+redis实现session共享

    Nginx+tomcat+redis实现session共享 1,安装nginx,使用yum -y install nginx 这是epel源中的,需要安装epel源. 2,配置nginx. 在ngin ...

  10. [转]C# 系统应用之鼠标模拟技术及自动操作鼠标

    原文网址: C# 系统应用之鼠标模拟技术及自动操作鼠标        游戏程序的操作不外乎两种——键盘输入控制和鼠标输入控制,几乎所有游戏中都使用鼠标来改变角色的位置和方向,本文主要是讲述如何使用C# ...