Python:信号量semaphore

本文介绍了Python中的信号量Semaphore,用于控制对共享资源的访问。通过信号量,可以限制同时访问资源的线程数量,避免了锁可能导致的死锁问题。文章探讨了信号量在连接池中的应用,并分析了其与锁的区别,以及在多线程中的工作原理。此外,还讨论了GIL(全局解释器锁)对Python多线程的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

semaphone信号量

信号量的应用举例

1、使用信号量对上例进行修改

1、从逻辑上分析

BoundedSemaphore类

1.2如果使用了信号量,但是还没有用完

1.3很多线程用完了信号量

信号量和锁

数据结构和GIL

GIL全局解释器锁

semaphone信号量

和Lock很像,信号量对象内部维护一个倒数计数器,每一次acquire都会减1,当acquire方法发现计数为0就阻塞请求的线程,直到其他的线程对信号量release后,计数大于0,恢复阻塞的线程

名称         含义
Semaphore(value=1) 构造方法。value小于0,抛ValueError异常
acquire(blocking=True,timeout=None) 获取信号量,计数器减1,获取成功返回True
release()         释放信号量,计数器加1

计数器永远不会低于0,因为acquire的时候,发现是0,都会被阻塞

import threading
import logging
import time

FORMAT = '%(asctime)-15s\t [%(threadName)s,%(thread)8d] %(message)s'
logging.basicConfig(level=logging.INFO,format=FORMAT)

def worker(s:threading.Semaphore):
    logging.info("in sub thread")
    logging.info(s.acquire())  #阻塞
    logging.info("sub thread over")


#信号量
s = threading.Semaphore(3)
logging.info(s.acquire())
print(s._value)
logging.info(s.acquire())
print(s._value)
logging.info(s.acquire())
print(s._value)

threading.Thread(target=worker,args=(s,)).start()


time.sleep(2)

logging.info(s.acquire(False))

logging.info(s.acquire(timeout=3))

#释放
logging.info("released")
s.release()

结果:

2021-06-24 23:33:30,508	 [MainThread,   17360] True
2021-06-24 23:33:30,508	 [MainThread,   17360] True
2021-06-24 23:33:30,508	 [MainThread,   17360] True
2021-06-24 23:33:30,509	 [Thread-1,   12680] in sub thread
2
1
0
2021-06-24 23:33:32,511	 [MainThread,   17360] False
2021-06-24 23:33:35,512	 [MainThread,   17360] False
2021-06-24 23:33:35,512	 [MainThread,   17360] released
2021-06-24 23:33:35,512	 [Thread-1,   12680] True
2021-06-24 23:33:35,512	 [Thread-1,   12680] sub thread over

信号量的应用举例

连接池:因为资源有限,且开启一个连接成本高,所以,使用连接池

一个简单的连接池:连接池应该有容量(总数),有一个工厂方法可以获取连接,能够把不用的连接返回,供其他调用者使用

class Conn:
    def __init__(self,name):
        self.name = name

class Pool:
    def __init__(self,count):
        self.count = count
        #池中是连接对象的列表
        self.pool = [self._connect("conn-{}".format(x)) for x in range(self.count)]
        
    def
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值