Python之信号量

发布时间:2024年01月23日

Python之信号量

什么是信号量
信号量详解
案例

什么是信号量

从某种意义上来说,信号量和线程池很像,他们都会根据你设置的线程上限值来自动帮你管理线程,但是信号量更倾向于‘锁’的概念

  • 信号量是一种并发控制机制,用于限制对共享资源的并发访问数量。通过控制信号量的计数器,可以允许多个线程或进程同时访问一定数量的资源。信号量常用于解决生产者-消费者问题、限流等场景。
  • 线程池是一组预先创建的线程集合,用于执行任务队列中的任务。线程池管理了可复用的线程,并根据需要分配任务给空闲的线程进行处理。线程池提供了更好的线程管理、调度和性能优化,适用于大量短期任务的并发处理。

信号量详解

先看一个简单的多线程案例:

import threading
import time

def work(name):
    print(f'{name}进厕所了')
    time.sleep(1)
    print(f'{name}出厕所了')
        
def main_thread():
    name = ['张三', '李四', '陈五', '王六', '横七', '竖八', ]
    t_l = []
    thread = [threading.Thread(target=work, args=(name[i],)) for i in range(5)]
    
    # 启动线程
    for t in thread:
        t.start()
        t_l.append(t)
    # 关闭线程
    for i in t_l:
        i.join()

main_thread()

打印结果:

image-20240121211329476

现在我想把条件改为厕所一次只能进一人该怎么修改代码呢,在之前或许我们只能想到互斥锁一类的限制机制,而现在我们可以用信号量(Semaphore)解决

首先定义全局变量:

import threading

sema = threading.Semaphore(count)

count默认为1,其意义是控制线程访问资源的数量,可以使用acquire()添加,以及release()释放,通俗来讲就相当于变量**sema是厕所,count就是厕所的坑位,acquire()一次就是进来一个人,release()一次就是出去一个人**

def work(name):
    # 添加
	sema.acquire()
    print(f'{name}进厕所了')
    time.sleep(1)
    # 释放
    sema.release()
    print(f'{name}出厕所了')
def work(name):
    with sema:
        sema.release()
        print(f'{name}进厕所了')
        time.sleep(1)
        print(f'{name}出厕所了')

两种写法一样

案例

知晓了信号量的用法那么就可以修改之前的案例了

import threading
import time

sema = threading.Semaphore(1)


def work(name):
    with sema:
        sema.acquire()
        print(f'{name}进厕所了')
        time.sleep(1)
        print(f'{name}出厕所了')


def main_thread():
    name = ['张三', '李四', '陈五', '王六', '横七', '竖八', ]
    t_l = []
    thread = [threading.Thread(target=work, args=(name[i],)) for i in range(5)]

    # 启动线程
    for t in thread:
        t.start()
        t_l.append(t)
    # 关闭线程
    for i in t_l:
        i.join()


main_thread()

结果:

image-20240121212427826

文章来源:https://blog.csdn.net/AZURE060606/article/details/135735608
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。