Semaphore信号量

稀土 2017-11-29

一、前言

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

二、semaphore

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

# -*- coding: UTF-8 -*-

import threading
import time


class MyThread(threading.Thread):

    def run(self):
        global num
        semaphore.acquire()  # 获取信号锁
        lock.acquire()
        num += 1
        print('run the thread: %s\n' % self.name)
        print('now the number is ', num)
        lock.release()
        time.sleep(1)
        semaphore.release()  # 释放信号锁

num = 0
lock = threading.Lock()
# 最多允许5个线程同时运行
semaphore = threading.BoundedSemaphore(5)

if __name__ == '__main__':

    for i in range(17):
        t = MyThread()
        t.start()

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

注:

  • 程序运行看上去是5个一组运行的,其实如果有个线程先完成了,释放了信号量,等待的线程就能获取信号量,但不超过5个。
  • 多个线程同时运行,还是会有线程安全问题,所以对共享资源竞争还是要加锁

三、使用场景

  1. 连接池,线程池,MySQL的有连接池,同一时间有个并发,能连多少个连接。
  2. 我们为了保证我的socket_server,可以使用semaphore来限制同一时间内连接数。

相关推荐