【python】-- 信号量(Semaphore)、event(红绿灯例子)

摘要:
前面在信号量中提到的线程锁(互斥锁)只允许一个线程同时更改数据,而信号量允许一定数量的线程同时更改。每次一个线程获得信号量,直到另一个线程释放信号量,它都是在同一时间。只能允许一组线程执行import_threadingimport_time_derun(n):
信号量(Semaphore)

之前讲的线程锁(互斥锁) 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。

1、信号量

  1. 是一个变量,控制着对公共资源或者临界区的访问。信号量维护着一个计数器,指定可同时访问资源或者进入临界区的线程数。 
  2. 每次有一个线程获得信号量时,计数器-1。若计数器为0,其他线程就停止访问信号量,直到另一个线程释放信号量

说白了就是在同一时间,可以只允许设定的数量的线程去执行

import threading
import time


def run(n):
    semaphore.acquire()   # 加信号量锁
    time.sleep(5)
    print("run the thread: %s
" % n)
    semaphore.release()   # 释放信号量锁


if __name__ == '__main__':

    semaphore = threading.BoundedSemaphore(5)  # 最多允许5个线程同时运行(Bounded:绑定,Semaphore:信号量)
    for i in range(20):
        t = threading.Thread(target=run, args=(i,))
        t.start()

while threading.active_count() != 1:
    pass
else:
    print('----all threads done---')

上面程序的执行,会让人感觉是:分了4组,前5个同时完成,然后又5个同时进去。但是实际的效果是:这5个里面如果有3个完成,就会立刻再放3个进去。不会等5个都完成,每出来1个就放进去1个,出来几个放进去几个

2、使用场景和总结

  1. 连接池,线程池,MySQL的有连接池,同一时间有多少个并发,就能连多少个连接。
  2. 我们为了保证我的socket_server,因为python不会默认现在你启动多少个线程,但是你启动的线程越多,就会把系统拉的越慢,就会把程序拉的越慢。这里就可以搞一个我同一时间放100线程个进来,就是用semaphore
  3. python3.x 虽然不加锁也是正确的,但是最好还是把锁加上
event(红绿灯例子)

日常生活中经常遇到红绿灯,我们就很好理解红绿灯的例子,就是红灯停,绿灯行。

  现在生成一个线程,这个线程我让它扮演红绿灯,它每过一段时间就变成绿灯,又过一段时间变成红灯,又变成黄灯。然后再生成3-5个线程作为车。车看见红灯,它就停下来等着,如果说是绿灯,车子就走。所以就涉及到红灯这个线程,红绿灯的这个线程就跟车线程之前产生了依赖了。就是红绿灯这个线程必须在绿灯的时候才能走,在红灯的时候就立刻停下来。所以互相之前,一个线程会根据另外一个线程的状态产生一些变化。类似这种场景的实现,就是:event,即事件。

1、事件的基础内置函数

event = threading.Event()   # 设置一个事件的全局变量

event.is_set()# 判断是否已经设置标志位。

event.wait()   # 没有设置标志位的时候会阻塞,一遇到标志位就不会阻塞 #判断是否已经设置标志位。

event.set()   # 设置标志位 ,标志位设置了,代表着绿灯,直接通行。

event.clear()   # 清除标志位,标志位被清空,代表红灯,wait等待变绿灯。

2、红绿灯例子

import threading
import time

event = threading.Event()  # 生成线程事件实例


def lighter():
    """
    模拟红绿灯
    :return:
    """
    count = 0
    event.set()   # 先设置标志位,代表绿灯
    while True:
        if count > 5 and count < 10:   # 改成红灯
            event.clear()    # 清除标志位,变成红灯
            print("

免责声明:内容来源于网络,仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇提升SQLite数据插入效率低、速度慢的方法通过sqlplus执行sql脚本并生成log下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

pyqt5学习之QThread

       pyqt的线程的使用非常简单-建立一个自定义的类(如thread),使它继承自QThread,并实现其run()方法即可; 在使用线程时可以直接得到thread实例,调用其start()函数即可启动线程。线程启动后,会自动调用其实现run方法,该方法就是线程的执行函数。        业务的线程任务就写在run()函数中,当run()退出之后...

远程线程注入DLL

0x00 原理介绍:上一篇文章介绍了在Windows下如何在其他进程创建一个远程线程:https://www.cnblogs.com/DarkBright/p/10820582.html 调用 CreateRemoteThread 创建远程线程所需要的过程函数的标准形式为: DWORD WINAPI ThreadProc( _In_ LPVOID lp...

Python queue (队列)

queue (队列) 主要作用 解耦,使程序实现松耦合(一个模块修改不会影响其他模块) 提高效率 队列与列表的关系 队列中数据只有一份,取出就没有了,区别于列表,列表数据取出只是复制了一份 分类 FIFO (先入先出) queue.Queue(maxsize=0)示例: import queue q = queue.Queue() q.put(1)...

经典的JAVA面试题

Java基础方面: 0、作用域public,private,protected,以及不写时的区别答:区别如下:作用域 当前类 同一package 子孙类 其他packagepublic √        √                  √       √protected √  √                  √        ×friendly...

Android优化总结

极力推荐文章:欢迎收藏Android 干货分享 文章转载网络 原文地址如下:https://juejin.im/post/5d072dbc51882540b7104709 1.OOM和崩溃优化 1.2 ANR优化 ANR的产生需要满足三个条件 主线程:只有应用程序进程的主线程响应超时才会产生ANR; 超时时间:产生ANR的上下文不同,超时时间也会...

关于Web服务器的认识

       马上就要毕业了,也要开始找工作了,大学写了这么多代码了,却没有好好总结一下常用的概念很是遗憾额,就通过这篇博客记录一下我最常用的一些知识好了。        说到Web服务器,有很多文章都介绍的很好,之前看到一篇非常不错的,对我帮助很大,可惜现在找不到原文了,看到博客园有人转载,我就在这里也记一下好了,在此非常感谢作者的分析,受益匪浅。   ...