python线程条件变量Condition(31)-创新互联

对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – 线程条件变量Condition.

为河西等地区用户提供了全套网页设计制作服务,及河西网站建设行业解决方案。主营业务为成都做网站、成都网站建设、河西网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

python 线程条件变量Condition(31)

一.线程条件变量Condition相关函数介绍

acquire() —  线程锁,注意线程条件变量Condition中的所有相关函数使用必须在acquire() /release() 内部操作;

release() — 释放锁,注意线程条件变量Condition中的所有相关函数使用必须在acquire() /release() 内部操作;

wait(timeout) —  线程挂起(阻塞状态),直到收到一个notify通知或者超时才会被唤醒继续运行(超时参数默认不设置,可选填,类型是浮点数,单位是秒)。wait()必须在已获得Lock前提下才能调用,否则会触发RuntimeError;

notify(n=1) —  通知其他线程,那些挂起的线程接到这个通知之后会开始运行,缺省参数,默认是通知一个正等待通知的线程,最多则唤醒n个等待的线程。notify()必须在已获得Lock前提下才能调用,否则会触发RuntimeError,notify()不会主动释放Lock;

notifyAll() —  如果wait状态线程比较多,notifyAll的作用就是通知所有线程;

python 线程条件变量Condition(31)

二.线程条件变量Condition原理

在前面的文章已经介绍过互斥锁,主要作用是并行访问共享资源时,保护共享资源,防止出现脏数据。python 条件变量Condition也需要关联互斥锁,同时Condition自身提供了wait/notify/notifyAll方法,用于阻塞/通知其他并行线程,可以访问共享资源了。可以这么理解,Condition提供了一种多线程通信机制,假如线程1需要数据,那么线程1就阻塞等待,这时线程2就去制造数据,线程2制造好数据后,通知线程1可以去取数据了,然后线程1去获取数据。

python 线程条件变量Condition(31)

三.线程条件变量Condition使用

案例一:成语接龙

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

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

# !usr/bin/env python

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

"""

@Author:何以解忧

@Blog(个人博客地址): shuopython.com

@WeChat Official Account(微信公众号):猿说python

@Github:www.github.com

@File:python_.py

@Time:2019/10/21 21:25

@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!

"""

# 导入线程模块

importthreading

# 创建条件变量condition

con=threading.Condition()

defthread_one(name):

# 条件变量condition 线程上锁

con.acquire()

print("{}:成语接龙准备好了吗".format(name))

# 唤醒正在等待(wait)的线程

con.notify()

# 等待对方回应消息,使用wait阻塞线程,等待对方通过notify唤醒本线程

con.wait()

print("{}:一干二净".format(name))

# 唤醒对方

con.notify()

# 等待消息答应

con.wait()

print("{}:一天就知道看抖音美女,给你来个简单点的,来了:毛手毛脚".format(name))

# 唤醒对方

con.notify()

# 等待消息答应

con.wait()

print("{}:哟哟哟,不错不错!".format(name))

# 唤醒对方

con.notify()

# 条件变量condition 线程释放锁

con.release()

defthread_two(name):

# 条件变量condition 线程上锁

con.acquire()

# wait阻塞状态,等待其他线程通过notify唤醒本线程

con.wait()

print("{}:准备好了~开始吧!".format(name))

# 唤醒对方

con.notify()

# 等待消息答应

con.wait()

print("{}:净你妹啊,没法接...来个简单点的...".format(name))

# 唤醒对方

con.notify()

# 等待消息答应

con.wait()

print("{}:嘿,这个我知道:脚踏实地".format(name))

# 唤醒对方

con.notify()

con.release()

if__name__=="__main__":

# 创建并初始化线程

t1=threading.Thread(target=thread_one,args=("A"))

t2=threading.Thread(target=thread_two,args=("B"))

# 启动线程 -- 注意线程启动顺序,启动顺序很重要

t2.start()

t1.start()

# 阻塞主线程,等待子线程结束

t1.join()

t2.join()

print("程序结束!")

输出结果:

1

2

3

4

5

6

7

8

A:成语接龙准备好了吗

B:准备好了~开始吧!

A:一干二净

B:净你妹啊,没法接...来个简单点的...

A:一天就知道看抖音美女,给你来个简单点的,来了:毛手毛脚

B:嘿,这个我知道:脚踏实地

A:哟哟哟,不错不错!

程序结束!

python 线程条件变量Condition(31)

案例二:生产者与消费者模式,以吃火锅为例:一盘老肉片有10块肉,吃完了又重新往锅里加….

生产者:往锅里加老肉片,每次加一盘(10块);

消费者:吃煮熟的肉片,没吃一片,肉片数量减一,吃完为止;

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

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

# 导入线程模块

importthreading

importtime

# 创建条件变量condition

con=threading.Condition()

meat_num=0

defthread_consumers():

# 条件变量condition 线程上锁

con.acquire()

# 全局变量声明关键字 global

globalmeat_num

meat_num=0

# 等待肉片下锅煮熟

con.wait()

whileTrue:

print("我来一块肉片...")

meat_num-=1

print("剩余肉片数量:%d"%meat_num)

time.sleep(0.5)

ifmeat_num==0:

# 肉片吃光了,通知老板添加肉片

print("老板,再来一份老肉片...")

con.notify()

# 肉片吃光了,等待肉片

con.wait()

# 条件变量condition 线程释放锁

con.release()

defthread_producer():

# 条件变量condition 线程上锁

con.acquire()

# 全局变量声明关键字 global

globalmeat_num

# 肉片熟了,可以开始吃了

meat_num=10

print("肉片熟了,可以开始吃了...")

con.notify()

whileTrue:

# 阻塞函数,等待肉片吃完的通知

con.wait()

meat_num=10

# 添加肉片完成,可以继续开吃

print("添加肉片成功!当前肉片数量:%d"%meat_num)

time.sleep(1)

con.notify()

con.release()

if__name__=="__main__":

# 创建并初始化线程

t1=threading.Thread(target=thread_producer)

t2=threading.Thread(target=thread_consumers)

# 启动线程 -- 注意线程启动顺序,启动顺序很重要

t2.start()

t1.start()

# 阻塞主线程,等待子线程结束

t1.join()

t2.join()

print("程序结束!")

输出结果:

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

肉片熟了,可以开始吃了...

我来一块肉片...

剩余肉片数量:9

我来一块肉片...

剩余肉片数量:8

我来一块肉片...

剩余肉片数量:7

我来一块肉片...

剩余肉片数量:6

我来一块肉片...

剩余肉片数量:5

我来一块肉片...

剩余肉片数量:4

我来一块肉片...

剩余肉片数量:3

我来一块肉片...

剩余肉片数量:2

我来一块肉片...

剩余肉片数量:1

我来一块肉片...

剩余肉片数量:0

老板,再来一份老肉片...

添加肉片成功!当前肉片数量:10

我来一块肉片...

剩余肉片数量:9

我来一块肉片...

剩余肉片数量:8

我来一块肉片...

剩余肉片数量:7

.............

注意:

1.全局变量要声明关键字 global;

2.注意线程的启动顺序,这个很重要;

四.重点总结

注意线程互斥锁Lock/线程事件Event/线程条件变量Condition三者的区别,场景不同,使用方式也不同,前两者一般可以作为简单的线程交互,线程条件变量Condition可以用于比较复杂的线程交互!

猜你喜欢:

1.python线程创建和参数传递

2.python线程互斥锁Lock

3.python线程事件Event

4.python return逻辑判断表达式

转载请注明:猿说Python » python条件变量Condition

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


本文名称:python线程条件变量Condition(31)-创新互联
当前网址:http://pwwzsj.com/article/ppicc.html