11.python并发入门(part6 Semaphore信号量)

一、什么是信号量。

信号量也是一种锁。

信号量的主要用途是用来控制线程的并发量的,BoundedSemaphore或Semaphore管理一个内置的计数器,每调用一次acquire()方法时,计数器-1,每调用一次release()方法时,内部计数器+1。

不过需要注意的是,Semaphore内部的计数器不能小于0!当它内部的计数器等于0的时候,这个线程会被锁定,进入阻塞状态,直到其他线程去调用release方法。

BoundedSemaphore与Semaphore的唯一区别在于前者将在调用release()时检查计数 器的值是否超过了计数器的初始值,如果超过了将抛出一个异常。

二、信号量使用的示例。

#!/usr/local/bin/python2.7

# -*- coding:utf-8 -*-

import threading

import time

semaphore = threading.Semaphore(5)   #设置同一次只能最多有5个线程通过。

def func():

if semaphore.acquire():

print threading.currentThread().getName() + "semaphore"

time.sleep(2)

semaphore.release()

for _ in range(20):

t1 = threading.Thread(target=func)

t1.start()

输出运行结果:

Thread-1semaphore

Thread-2semaphore

Thread-3semaphore

Thread-4semaphore

Thread-5semaphore

Thread-6semaphore

Thread-7semaphore

Thread-8semaphore

Thread-9semaphore

Thread-10semaphore

Thread-13semaphore

Thread-11semaphore

Thread-12semaphore

Thread-14semaphore

Thread-15semaphore

Thread-17semaphore

Thread-20semaphore

Thread-19semaphore

Thread-18semaphore

Thread-16semaphore

一次最多放行了5个线程,这个和停车位的概念有点像。

三、信号量与递归锁的区别。

个人理解~信号量和递归锁的差别是不是,在信号量中,同一把锁,多个线程可以操作同一个共享数据,在递归锁在锁被释放之前一个线程只能操作一个共享数据。

时间: 2024-11-04 11:14:48

11.python并发入门(part6 Semaphore信号量)的相关文章

11.python并发入门(part10 多进程之间实现通信,以及进程之间的数据共享)

一.进程队列. 多个进程去操作一个队列中的数据,外观上看起来一个进程队列,只是一个队列而已,单实际上,你开了多少个进程,这些进程一旦去使用这个队列,那么这个队列就会被复制多少份. (队列=管道+锁) 这么做的主要原因就是,不同进程之间的数据是无法共享的. 下面是使用进程队列使多进程之间互相通信的示例: 下面这个例子,就是往进程队列里面put内容. #!/usr/local/bin/python2.7 # -*- coding:utf-8 -*- import multiprocessing de

11.python并发入门(part2 threading模块的基本使用)

一.在使用python多线程之前,你需要知道的. python的多线程中,实现并发是没有问题的,但是!!是无法实现真正的并行的. 这是因为python内部有个GIL锁(全局解释器锁),这个锁限制了在同一时刻,同一个进程中,只能有一个线程被运行!!! 二.threading模块的基本使用方法. 可以使用它来创建线程.有两种方式来创建线程. 1.通过继承Thread类,重写它的run方法. 2.创建一个threading.Thread对象,在它的初始化函数__init__中将可调用对象作为参数传入.

11.python并发入门(part12 初识协程)

一.协程的简介. 协程,又被称为微线程,虽然是单进程,单线程,但是在某种情况下,在python中的协程执行效率会优于多线程. 这是因为协程之间的切换和线程的切换是完全不一样的!协程的切换是由程序自身控制的(程序的开发者使用yield去进行控制,协程和协程之间的切换是可控制的,想什么时候切换就什么时候切换). 当使用多线程时,开的线程越多,协程的优势就越明显. 协程的另一个优点,就是无需锁机制,因为协程只有一个进程,和线程,不存在多线程或者多进程之间访问公共资源的冲突,所以说,在协程中无需加锁,如

11.python并发入门(part9 多线程模块multiprocessing基本用法)

一.回顾多继承的概念. 由于GIL(全局解释器锁)的存在,在python中无法实现真正的多线程(一个进程里的多个线程无法在cpu上并行执行),如果想充分的利用cpu的资源,在python中需要使用进程. 二.multiprocessing模块的简介. multiprocessing是python中用来管理多进程的包,与threading用法非常类似,它主要使用multiprocessing.Process对象来创建一个进程对象,该进程可以运行在python的函数中. 该Process(进程)对象

11.python并发入门(part11 进程同步锁,以及进程池,以及callback的概念)

一.关于进程锁. 其实关于进程锁没啥好讲的了,作用跟线程的互斥锁(又叫全局锁也叫同步锁)作用几乎是一样的. 都是用来给公共资源上锁,进行数据保护的. 当一个进程想去操作一个公共资源,它就可以给公共资源进程"上锁"的操作,其他进程如果也想去访问或者操作这个公共资源,那么其他的进程只能阻塞,等待刚刚的进程把锁释放,下一个进程才可以对这个公共资源进行操作. 下面是个关于进程锁的使用示范: #!/usr/local/bin/python2.7 # -*- coding:utf-8 -*- im

11.python并发入门(part7 线程队列)

一.为什么要用队列? 队列是一种数据结构,数据结构是一种存放数据的容器,和列表,元祖,字典一样,这些都属于数据结构. 队列可以做的事情,列表都可以做,但是为什么我们还要去使用队列呢? 这是因为在多线程的情况下,列表是一种不安全的数据结构. 为什么不安全?可以看下面这个例子: #开启两个线程,这两个线程并发从列表中移除一个元素. import threading import time l1 = [1,2,3,4,5] def pri(): while l1: a = l1[-1] print a

11.python并发入门(part1 初识进程与线程,并发,并行,同步,异步)

一.什么是进程? 在说什么是进程之前,需要先插入一个进程切换的概念! 进程,可以理解为一个正在运行的程序. 现在考虑一个场景,假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源.你是不是已经想到在程序A读取数据的过程中,让程序B去执行,当程序A读取完数据之后,让程序B暂停.这当然没问题,但这里有一个关键词:切换. 既然是切换,那么这就涉及到了状态的保存,状态的恢复,加上程序A与

11.python并发入门(part4 死锁与递归锁)

一.关于死锁. 死锁,就是当多个进程或者线程在执行的过程中,因争夺共享资源而造成的一种互相等待的现象,一旦产生了死锁,不加人工处理,程序会一直等待下去,这也被称为死锁进程. 下面是一个产生"死锁"现象的例子: import threading import time lock_a = threading.Lock() lock_b = threading.Lock() class test_thread(threading.Thread): def __init__(self): su

11.python并发入门(part15 关于I/O多路复用)

一.为什么要产生I/O多路复用? 两个主机之间通信,主机A和主机B都需要开启socket,主机A首先要等待客户端来进行连接,这是会发起一个recvfrom的系统调用,如果主机B一直没有去连接主机A,没有给主机A发送任何数据,进程就会被阻塞,无法去做其他的事情(默认的阻塞I/O模型),一直阻塞到主机B去连接主机A,主机A收到了这个连接. 其实这种模式在单服务器,单客户端(两台主机之间单独通信)没有什么问题,如果说是多并发场景呢?服务端阻塞与第一个客户端发来的socket对象中,另外一个客户端2要发