热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python线程条件变量Condition(31)

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

对于线程与线程之间的交互我们在前面的文章已经介绍了 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



推荐阅读
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • IB 物理真题解析:比潜热、理想气体的应用
    本文是对2017年IB物理试卷paper 2中一道涉及比潜热、理想气体和功率的大题进行解析。题目涉及液氧蒸发成氧气的过程,讲解了液氧和氧气分子的结构以及蒸发后分子之间的作用力变化。同时,文章也给出了解题技巧,建议根据得分点的数量来合理分配答题时间。最后,文章提供了答案解析,标注了每个得分点的位置。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
author-avatar
嘉sen
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有