本文摘自php中文网,作者不言,侵删。
本篇文章给大家带来的内容是关于python中线程同步原语的代码示例,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
Threading模块是python3里面的多线程模块,模块内集成了许多的类,其中包括Thread,Condition,Event,Lock,Rlock,Semaphore,Timer等等。下面这篇文章主要通过案例来说明其中的Event和Segmaphore(Boundedsegmaphore)的使用。
Event
Event类内部保存着一个flags参数,标志事件的等待与否。
Event类实例函数
1. set() 将flags设置为True,事件停止阻塞
2. clear() 将flags重新设置为False,删除flags,事件重新阻塞
3. wait() 将事件设置为等待状态
4.is_set()判断flags是否被设置,如果被设置返回True,否则返回False
(1)单个事件等待其他事件的发生
具体代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | from time import ctime,sleep
event = Event()
def event_wait():
print (ctime())
event.wait()
print ( '这是event_wait方法中的时间' ,ctime())
def event_set(n):
sleep(n)
event.set()
print ( '这是event_set方法中的时间' , ctime())
thread1 = Thread(target=event_wait)
thread2 = Thread(target=event_set,args=(3,))
thread1.start()
thread2.start()
|
结果:
1 2 3 | Sat Nov 17 10:01:05 2018
这是event_wait方法中的时间 Sat Nov 17 10:01:08 2018
这是event_set方法中的时间 Sat Nov 17 10:01:08 2018
|
(2)多个事件先后发生
下面以赛跑来作为例子。假设5条跑道上,每条跑道各有一名运动员,分别为ABCDE。
具体代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | from threading import Event
from threading import Thread
import threading
event = Event()
def do_wait(athlete):
racetrack = threading.current_thread().getName()
print ( '%s准备就绪' % racetrack)
event.wait()
print ( '%s听到枪声,起跑!' %athlete)
thread1 = Thread(target=do_wait,args=( "A" ,))
thread2 = Thread(target=do_wait,args=( "B" ,))
thread3 = Thread(target=do_wait,args=( "C" ,))
thread4 = Thread(target=do_wait,args=( "D" ,))
thread5 = Thread(target=do_wait,args=( "E" ,))
threads = []
threads.append(thread1)
threads.append(thread2)
threads.append(thread3)
threads.append(thread4)
threads.append(thread5)
for th in threads:
th.start()
event.set() #这个set()方法很关键,同时对5个线程中的event进行set操作
|
结果:
1 2 3 4 5 6 7 8 9 10 | Thread-1准备就绪
Thread-2准备就绪
Thread-3准备就绪
Thread-4准备就绪
Thread-5准备就绪
E听到枪声,起跑!
A听到枪声,起跑!
B听到枪声,起跑!
D听到枪声,起跑!
C听到枪声,起跑!
|
可以看出多个线程中event的set()是随机的,其内部的实现是因为一个notify_all()方法。这个方法会一次性释放所有锁住的事件,哪个线程先抢到线程运行的时间片,就先释放锁。
之所以能够只调用一个set()函数就可以实现所有event的退出阻塞,是因为event.wait()是在线程内部实现的,而set()函数是在进程中调用,python多线程共享一个进程内存空间。如果是在不同进程中调用这两个函数则无法实现。
BoundedSegmaphore
如果在主机执行IO密集型任务的时候再执行这种短时间内完成大量任务(多线程)的程序时,计算机就有很大可能会宕机。
这时候就可以为这段程序添加一个计数器(counter)功能,来限制一个时间点内的线程数量。当每次进行IO操作时,都需要向segmaphore请求资源(锁),如果没有请求到,就阻塞等待,请求成功才就像执行任务。
BoundedSegmaphore和Segmaphore的区别
BoundedSegmaphore请求的锁数量固定为传入参数,而Segmaphore请求的锁数量可以超过传入的参数。
主要函数:
1. acquire() 请求锁
2. release() 释放锁
下面以一个租房的例子来说明这种固定锁数量的机制。假设一家小公寓有6间房,原本有2个住户在住着。
具体代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | from threading import BoundedSemaphore,Lock,Thread
from time import sleep
from random import randrange
lock = Lock()
num = 6
hotel = BoundedSemaphore(num)
def logout():
lock.acquire()
print ( 'I want to logout' )
print ( 'A customer logout...' )
try :
hotel.release()
print ( 'Welcome again' )
except ValueError:
print ( 'Sorry,wait a moment.' )
lock.release()
def login():
lock.acquire()
print ( 'I want to login' )
print ( 'A customer login...' )
if hotel.acquire(False):
print ( 'Ok,your room number is...' )
else :
print ( 'Sorry,our hotel is full' )
lock.release()
#房东
def producer(loops):
for i in range(loops):
logout()
print ( '还剩%s' % hotel._value, '房间' )
sleep(randrange(2))
#租客
def consumer(loops):
for i in range(loops):
login()
print ( '还剩%s' % hotel._value, '房间' )
sleep(randrange(2))
def main():
print ( 'Start' )
room_num = hotel._value
print ( 'The hotel is full with %s room' %room_num)
#原本有2个住户
hotel.acquire()
hotel.acquire()
thread1 = Thread(target=producer,args=(randrange(2,8),))
thread2 = Thread(target=consumer,args=(randrange(2,8),))
thread1.start()
thread2.start()
if __name__ == '__main__' :
main()
|
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | The hotel is full with 6 room
I want to logout
A customer logout...
Welcome again
还剩5 房间
I want to logout
A customer logout...
Welcome again
还剩6 房间
I want to login
A customer login...
Ok,your room number is...
还剩5 房间
I want to login
A customer login...
Ok,your room number is...
还剩4 房间
|
可以看出,房间数目永远不会超过6,因为_value值(BoundedSegmaphore内部的计数器counter)一定是传入的参数6。
以上就是python中线程同步原语的代码示例的详细内容,更多文章请关注木庄网络博客!!
相关阅读 >>
Python中的模块是什么?3分钟搞懂Python中的模块问题
Python为什么要配置环境变量
Python的format怎么用
Python通过什么实现映射
Python实现各种最优化算法
Python将dataframe的某一列作为index的方法
Python中py2exe打包工具的用法详解
Python 异常处理机制详解
Python利用不到一百行代码实现一个小siri
Python步长什么意思
更多相关阅读请进入《Python》频道 >>
人民邮电出版社
python入门书籍,非常畅销,超高好评,python官方公认好书。
转载请注明出处:木庄网络博客 » python中线程同步原语的代码示例