python 线程条件变量Condition(31)
admin
2023-01-29 03:20:03
0

对于线程与线程之间的交互我们在前面的文章已经介绍了 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:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!

"""

 

# 导入线程模块

import threading

 

# 创建条件变量condition

con = threading.Condition()

 

def thread_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()

 

def thread_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

# 导入线程模块

import threading

import time

 

# 创建条件变量condition

con = threading.Condition()

meat_num = 0

 

def thread_consumers():

    # 条件变量condition 线程上锁

    con.acquire()

    

    # 全局变量声明关键字 global

    global meat_num

    meat_num = 0

 

    # 等待肉片下锅煮熟

    con.wait()

    while True:

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

        meat_num -= 1

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

        time.sleep(0.5)

        if meat_num == 0:

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

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

            con.notify()

            # 肉片吃光了,等待肉片

            con.wait()

 

    # 条件变量condition 线程释放锁

    con.release()

 

 

def thread_producer():

    # 条件变量condition 线程上锁

    con.acquire()

    # 全局变量声明关键字 global

    global meat_num

 

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

    meat_num = 10

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

    con.notify()

    while True:

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

        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


上一篇:Linux安装Python 3.8.1

下一篇:08-01 模块

相关内容

热门资讯

李尔平院士:为智能时代筑牢“电... 封面新闻记者 刘叶 车家竹 摄影 何宏杰 在人工智能浪潮席卷全球的今天,一个名为“电磁兼容”的专业领...
江苏、上海等地将机器人纳入“国... 南都讯记者杨文君 发自北京 7月22日,记者从商务部获悉,2026年上半年,消费品以旧换新累计带动相...
“引力一号”成功发射一箭九星,... IT之家 7 月 22 日消息,今天上午,引力一号运载火箭在上海东部海域点火升空,成功将 9 颗卫星...
特朗普向4名士兵灵柩敬礼,均阵... 当地时间7月22日,美国总统唐纳德·特朗普率领数位高官,来到位于特拉华州的多佛空军基地,参加了阵亡美...
“特朗普这么干,10年后,美国... 据南华早报7月23日报道,分析人士认为,北京如今在语言能力方面更善于解读美国战略,而美国却难以做到同...
墨西哥一市长在市政厅内遭枪击死... 综合法新社等多家外媒报道,墨西哥检方当地时间22日通报称,该国中部一地方市长在市政厅内遭枪击死亡。今...
编造传播涉汛涉灾网络谣言,公安... 为有力保障防汛救灾工作,公安机关网安部门依托“净网—2026”专项行动,持续严厉打击编造传播涉汛等涉...
松下洗衣机洗衣服操作方法 **洗衣机是一种高品质的洗衣设备,它具有简单易用的设计,使用方便。如果你是第一次使用一台**洗衣机,...
小天鹅自动洗衣机操作方法 小天鹅自动洗衣机是目前市场上比较主流的一种洗衣机,它因为具有自动化操作、节能环保、节约用水等优点,受...
全自动洗衣机进水操作方法 全自动洗衣机是现代家庭中常用的一种家电产品,使用它能够帮助我们更加方便快捷地完成家务工作,但是很多人...