Python 从入门到实战39(线程间的通信)

        我们的目标是:通过这一套资料学习下来,可以熟练掌握python基础,然后结合经典实例、实践相结合,使我们完全掌握python,并做到独立完成项目开发的能力。

上篇文章我们讨论了通过创建线程的相关知识。今天学习一下线程间通信的相关知识。

1、线程间可以直接共享信息吗?

        我们在之前的章节中学习了进程,并且知道进程之间不能直接共享信息。可以使用队列来进行进程之间的通信。那线程之间能够之间共享信息吗?答案是可以。

举例说明:

import threading
#创建两个线程分别对全局变量进行操作,检查结果,确认线程间能之间共享信息

def plus():        #加法
    print("**********子线程加法开始************")
    global test_number
    test_number +=100
    print("test_number +100 is %d"%test_number)
    print("**********子线程加法结束************")

def minus():
    print("**********子线程减法开始************")
    global test_number
    test_number -= 100
    print("test_number -100 is %d" % test_number)
    print("**********子线程减法结束************")

test_number = 200    #定义一个全局变量
def main():
    print("*************主线程开始***************")
    print("test_number is %d"%test_number)  #测试值开始的值为200
    thread1 = threading.Thread(target=plus)  #使用测试值加100
    thread2 = threading.Thread(target=minus)

    thread1.start()   #子线程启动
    thread2.start()
    thread1.join()     #等待子线程结束
    thread2.join()
    print("*************主线程结束***************")


if __name__=="__main__":
    main()

输出结果参考:

2、互斥锁

1)互斥锁的简介

上面我们举例说明了,线程是可以对全局变量进行随意修改。这样也就可能造成多线程之间对全局变量的混乱。如何解决这一问题呢?例如大家都排队上厕所,一种防止他人进入房间的简单方法就是进门后就上锁,后面的人就只能继续等待。

在程序中叫互斥锁(mutual exclusion 缩写为Mutex),防止多个线程同时读写某一块内存区域。互斥锁为资源引入一个状态,即锁定或者非锁定。某个线程要更改共享数据时,先将其锁定。

2)使用互斥锁

在threading 模块中使用lock 类可以方便的处理锁定。lock 类有两个方法,即acquire()锁定和release()释放锁。用法如下:

mutex = threading.Lock()     #创建锁

mutex.acquire([blocking])     #锁定

mutex.release()          #释放锁

参数说明:

acquire([blocking])----获取锁定,如果有必要,则需要阻塞到锁定被释放位置。若是提供blocking 参数并将它设置为False:当无法获取锁定时将立即返回False;当成功获取锁定时,将返回True.

release()------释放一个锁定,当锁处于未锁定状态时,或者从原本调用acquire()方法的不同线程中调用此方法,将会出现错误。

举例说明:

#使用互斥锁实现多人同时订购火车票的功能
#如某车次有100张票,10个人同时抢购,每售出一张,显示一次剩余火车票数量。

ticket_number = 100
mutex = Lock()  #实例化lock 类
def task():
    global ticket_number
    mutex.acquire()
    temp = ticket_number
    time.sleep(0.2)
    ticket_number = temp -1
    print("购买成功,剩余%d张火车票"%ticket_number)
    mutex.release()

def main():

    thread_L = []   #初始化一个列表
    for i in range(10):
        thread = Thread(target=task)  #实例化线程类,创建线程
        thread_L.append(thread)       #将线程实例存入列表中
        thread.start()      #启动线程
    for thread in thread_L:
        thread.join()       #等待子线程结束

if __name__=="__main__":
    main()

输出参考:

购买成功,剩余99张火车票

购买成功,剩余98张火车票

购买成功,剩余97张火车票

购买成功,剩余96张火车票

购买成功,剩余95张火车票

购买成功,剩余94张火车票

购买成功,剩余93张火车票

购买成功,剩余92张火车票

购买成功,剩余91张火车票

购买成功,剩余90张火车票

Process finished with exit code 0

上述代码中创建了10个线程,全部执行task()函数。为解决资源竞争问题,使用mutex.acquire()函数实现资源锁定。每次只有一个线程执行task()函数。

3、线程间通信-by queue

我们已经直到multiprocessing 模块的Queue 队列可以实现进程间通信,同样在线程间也可以使用Queue 队列进行通信。不同之处在于需要使用queue 中Queue 队列,而不是multiprocessing 模块的Queue 队列。但是,两者的Queue 队列使用的方法相同。

举例说明:

#使用队列模式模拟生产者和消费者,定义一个生产者类Producer 和一个消费者类Consumer.
#生产者共生产5件商品,并将5件商品依次写入队列中,而消费者依次从队列中取出产品
#生产者类
class Producer(threading.Thread):
    def __init__(self,name,queue):
        threading.Thread.__init__(self,name=name)
        self.data = queue
    def run(self):
        for i in range(5):
            print("生产者%s将产品%d加入队列!"%(self.name,i))
            self.data.put(i)
            time.sleep(random())
        print("生产者%s完成!"%self.name)

#消费者类,子线程类
class Consumer(threading.Thread):
    def __init__(self,name,queue):
        threading.Thread.__init__(self, name=name)
        self.data = queue
    def run(self):
        for i in range(5):
            val = self.data.get()  #取出队列中数据
            print("消费者%s将产品%d从队列中取出!" % (self.name, val))
            time.sleep(random())
        print("消费者%s完成!"%self.name)
def main():
    print("-----------主线程开始-----------")
    queue = Queue()   #实例化队列
    producer = Producer("Producer",queue)  #实例化线程producer,并将其传入队列中作为参数,子线程
    consumer = Consumer("Consumer",queue)
    producer.start()  #线程启动
    consumer.start()
    producer.join()   #等待子线程结束
    consumer.join()
    print("-----------主线程结束-----------")

if __name__=="__main__":
    main()

输出结果参考:

-------------------------------------------------------------------------------------------------------------------

-----------主线程开始-----------

生产者Producer将产品0加入队列!

消费者Consumer将产品0从队列中取出!

生产者Producer将产品1加入队列!

消费者Consumer将产品1从队列中取出!

生产者Producer将产品2加入队列!

消费者Consumer将产品2从队列中取出!

生产者Producer将产品3加入队列!

消费者Consumer将产品3从队列中取出!

生产者Producer将产品4加入队列!

生产者Producer完成!

消费者Consumer将产品4从队列中取出!

消费者Consumer完成!

-----------主线程结束-----------

Process finished with exit code 0

-------------------------------------------------------------------------------------------------------------------

今天先写学习到这里了,每天进步一点点。明天也要加油啊!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/457068.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

配置nginx服务通过ip访问多网站

文章目录 第一种方法第二种方法 先关闭防火墙 # systemctl stop firewalld # setenforce 0第一种方法 #mntui 第二种方法 # vim /etc/nginx/conf.d/test_ip.conf # cat /etc/nginx/conf.d/test_ip.conf server {listen 192.168.234.100:80;#server_nameroot /test/100;loca…

PostgreSQL使用clickhouse_fdw访问ClickHouse

Postgres postgres版本:16(测试可用)docker 安装 插件安装 clickhouse_fdw: https://github.com/ildus/clickhouse_fdw 安装命令 git clone gitgithub.com:ildus/clickhouse_fdw.git cd clickhouse_fdw mkdir build && cd build…

文件下载漏洞

文件安全 文件下载 常见敏感信息路径 Windows C:\boot.ini //查看系统版本 C:\Windows\System32\inetsrv\MetaBase.xml //IIS配置文件 C:\Windows\repair\sam //存储系统初次安装的密码 C:\Program Files\mysql\my.ini //Mysql配置 C:\Program Files\mysql\data\mysql\user.…

【目标检测01】真实框、预测框、锚框和交并比IoU

文章目录 1. 任务定义2. 基本概念2.1 边界框(bounding box)2.2 真实框、预测框和锚框2.3 交并比 (IoU)2.4 代码实现 1. 任务定义 目标检测的主要目的是让计算机可以自动识别图片或者视频帧中所有目标的类别,并在该目标周围绘制边界框&#x…

Midjourney上线图像编辑,他们终于知道什么叫开放了。

Midjourney作为文生图领域毋庸置疑的头号选手,之前几乎每次推新都非常惊艳。 前段时间也看到很多消息说Midjourney v7已经训练完毕了,但我左等右等,没等到v7的发布。 却提前等来了可能会更加好玩的一个功能——图像编辑模式。 Midjourney的…

2024-网鼎杯第二次模拟练习-web02

进入做题页面,经过信息搜集和目录扫描,发现只有一个公告是可以利用的 http://0192c74e0f9871c2956795c804c3dde3.8nfp.dg01.wangdingcup.com:43014/OA_announcement.php?id1 这个后面有一个明显的注入点,经过多次刷新和快速刷新后发现&…

Linux中DNS搭建

文章目录 一、DNS介绍1.1、DNS是什么1.2、DNS的工作原理1.3、DNS的域名结构 二、Bind介绍2.1、bind概述2.2、bind主要配置文件 三、DNS安装四、主要配置文件解析(除/etc/named.conf)4.1、/etc/named.rfc1912.zones4.2、/etc/rc.d/init.d/named4.3、/etc/…

批处理操作的优化

原来的代码 Override Transactional(rollbackFor Exception.class) public void batchAddQuestionsToBank(List<Long> questionIdList, Long questionBankId, User loginUser) {// 参数校验ThrowUtils.throwIf(CollUtil.isEmpty(questionIdList), ErrorCode.PARAMS_ERR…

基于neo4j的新冠治疗和新冠患者轨迹的知识图谱问答系统

毕业设计还在苦恼选题&#xff1f;想做一个兼具前沿性和实用性的技术项目&#xff1f;了解下这款基于Neo4j的新冠治疗和患者轨迹的知识图谱问答系统吧&#xff01; 系统可以实现两大功能模块&#xff1a;新冠医疗信息和患者活动轨迹的展示与问答。通过图谱技术&#xff0c;你可…

CLion远程开发Ubuntu,并显示helloworld文字框

1.CLion的介绍以及其在远程开发上的优点 1&#xff09;CLion 是一个由 JetBrains 开发的跨平台 C/C 集成开发环境&#xff08;IDE&#xff09;&#xff0c;功能强大。 2&#xff09;CLion的优点&#xff1a; 远程工具链支持&#xff1a;CLion 支持通过 SSH 连接到远程 Ubuntu…

【AIGC】优化长提示词Prompt:提升ChatGPT输出内容的准确性与实用性

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;长提示词的挑战&#x1f4af;谷歌的优化长提示词技术关键因素分析 &#x1f4af;长提示词的设计原则&#x1f4af;优化长提示词的新框架方法&#x1f4af;实验结果分析不…

解决Github下载速度慢的问题

1. 方式一 先把hosts文件先复制一份到其他文件夹下&#xff0c;以免造成不小心改动出现的后果在C盘的C:\Windows\System32\drivers\etc 下的hosts文件 用编辑器打开后&#xff0c;在末尾处添加访问如下的两个网站所返回的两个IP https://github.com.ipaddress.com/ http://gi…

尝鲜electron --将已有vue/react项目转换为桌面应用

Electron 是一个强大的框架&#xff0c;它允许开发者使用 Web 技术&#xff08;如 HTML、CSS 和 JavaScript&#xff09;构建跨平台的桌面应用程序。它结合了 Node.js 和 Chromium&#xff0c;就相当于在桌面程序web和游览器,所以只需要简单的配置就可以转换为桌面应用 注意:无…

IDEA关联Tomcat——最新版本IDEA 2024

1.链接Tomcat到IDEA上 添加Tomcat到IDEA上有两种方式&#xff1a; 第一种&#xff1a; &#xff08;1&#xff09;首先&#xff0c;来到欢迎界面&#xff0c;找到左侧的Customize选项 &#xff08;2&#xff09;然后找到Build、Execution、Deployment选项 &#xff08;3&am…

Prism 四事件聚合器

#1024程序员节&#xff5c;征文# 不废话&#xff0c;直接上代码一个简单的示例。 1、事件聚合 创建一个文件夹EventBLL&#xff0c;添加EventDemo.cs&#xff0c;代码如下。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using …

.NET使用QuestPDF高效地生成PDF文档

前言 在.NET平台中操作生成PDF的类库有很多如常见的有iTextSharp、PDFsharp、Aspose.PDF等&#xff0c;今天我们分享一个用于生成PDF文档的现代开源.NET库&#xff1a;QuestPDF&#xff0c;本文将介绍QuestPDF并使用它快速实现发票PDF文档生成功能。 QuestPDF介绍 QuestPDF 是…

什么样的JSON编辑器才好用

简介 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也便于机器解析和生成。随着互联网和应用程序的快速发展&#xff0c;JSON已经成为数据传输和存储的主要格式之一。在处理和编辑JSON数据…

Python开发日记 -- 实现bin文件的签名

目录 1.数据的不同表现形式签名值不一样&#xff1f; 2.Binascii模块简介 3.问题定位 4.问题总结 1.数据的不同表现形式签名值不一样&#xff1f; Happy Muscle试运行了一段时间&#xff0c;组内同事再一次提出了新的需求&#xff1a;需要对bin文件签名。 PS&#xff1a;服…

vue3 树型视图,利用自定义SFC来定义一个TreeItem,然后进行渲染出一个树形。

1、我们在各种项目中都会碰到树形的视图&#xff0c;所以说这个还是很重要的。 2、项目中我们一般会用现成的组件&#xff08;ant-design、element&#xff09;来处理&#xff0c;这里我们使用自定义的方法&#xff0c;提供一个data来处理&#xff0c;比如这样&#xff1a; 最…

【大数据分析与挖掘模型】matlab实现——非线性回归预测模型

一、实验目的 掌握有关非线性回归的理论知识&#xff0c;通过变量代换把本来应该用非线性回归处理的问题近似转化为线性回归问题&#xff0c;并进行分析预测。 二、实验任务 对非线性回归实例进行编码计算&#xff0c;实例如下&#xff1a; 三、实验过程 1.运行非线性回归中…