python中线程同步原语的代码示例


本文摘自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》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...