【Python快速上手(二十三)】

目录

  • Python快速上手(二十三)
    • Python3 多线程
      • 1. 线程的创建
      • 2. 线程同步
        • 2.1 锁(Lock)
        • 2.2 信号量(Semaphore)
        • 2.3 事件(Event)
        • 2.4 条件(Condition)
      • 3. 线程优先级队列(Queue)
      • 总结

Python快速上手(二十三)

Python3 多线程

多线程类似于同时执行多个不同程序,多线程运行有如下优点:

  • 使用线程可以把占据长时间的程序中的任务放到后台去处理。
  • 用户界面可以更加吸引人,比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。
  • 程序的运行速度可能加快。
  • 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。
  • 多线程是一种并发编程的技术,允许程序同时执行多个线程。在Python中,我们可以使用threading模块来实现多线程编程。

Python3 线程中常用的两个模块为:

  • _thread
  • threading(推荐使用)
    thread 模块已被废弃。可以使用 threading 模块代替。所以,在 Python3 中不能再使用"thread" 模块。为了兼容性,Python3 将 thread 重命名为 “_thread”。在本文中,我们将详细讲解Python3中的多线程编程,包括线程的创建、同步、优先级队列等内容。

1. 线程的创建

在Python中,可以通过创建Thread类的实例来创建线程。以下是一个简单的示例代码:

#!/usr/bin/python3import threading
import timeexitFlag = 0class myThread (threading.Thread):def __init__(self, threadID, name, delay):threading.Thread.__init__(self)self.threadID = threadIDself.name = nameself.delay = delaydef run(self):print ("开始线程:" + self.name)print_time(self.name, self.delay, 5)print ("退出线程:" + self.name)def print_time(threadName, delay, counter):while counter:if exitFlag:threadName.exit()time.sleep(delay)print ("%s: %s" % (threadName, time.ctime(time.time())))counter -= 1# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)# 开启新线程
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print ("退出主线程")

以上程序执行结果如下;

开始线程:Thread-1
开始线程:Thread-2
Thread-1: Wed Jan  5 17:34:54 2022
Thread-2: Wed Jan  5 17:34:55 2022
Thread-1: Wed Jan  5 17:34:55 2022
Thread-1: Wed Jan  5 17:34:56 2022
Thread-2: Wed Jan  5 17:34:57 2022
Thread-1: Wed Jan  5 17:34:57 2022
Thread-1: Wed Jan  5 17:34:58 2022
退出线程:Thread-1
Thread-2: Wed Jan  5 17:34:59 2022
Thread-2: Wed Jan  5 17:35:01 2022
Thread-2: Wed Jan  5 17:35:03 2022
退出线程:Thread-2
退出主线程

2. 线程同步

在多线程编程中,线程同步是非常重要的,它用于确保多个线程之间的数据访问和操作是安全的,避免出现竞争条件和数据不一致的情况。Python提供了多种线程同步机制,包括锁、信号量、事件、条件等。

2.1 锁(Lock)

锁是最基本的线程同步机制,通过获取锁可以阻止其他线程访问共享资源,从而确保数据的一致性。在Python中,可以使用threading.Lock类来创建锁对象,并通过acquire()和release()方法来获取和释放锁。

import threadinglock = threading.Lock()def increment_counter():global counterlock.acquire()counter += 1lock.release()

在上面的示例中,我们创建了一个锁对象lock,然后在increment_counter函数中使用acquire()方法获取锁,对counter变量进行操作后再通过release()方法释放锁。

2.2 信号量(Semaphore)

信号量是一种更加通用的线程同步机制,它可以控制多个线程同时访问共享资源的数量。在Python中,可以使用threading.Semaphore类来创建信号量对象,并通过acquire()和release()方法来控制资源的访问。

import threadingsemaphore = threading.Semaphore(2) # 允许同时有2个线程访问共享资源def use_resource():semaphore.acquire()# 访问共享资源semaphore.release()

在上面的示例中,我们创建了一个信号量对象semaphore,并设置允许同时有2个线程访问共享资源。线程在访问资源前需要先通过acquire()方法获取信号量,访问完成后再通过release()方法释放信号量。

2.3 事件(Event)

事件是一种线程同步机制,用于实现线程之间的通信和协调。在Python中,可以使用threading.Event类来创建事件对象,并通过set()和clear()方法来设置和清除事件。

import threadingevent = threading.Event()def wait_for_event():event.wait() # 等待事件被设置# 处理事件def set_event():event.set() # 设置事件

在上面的示例中,我们创建了一个事件对象event,线程可以通过wait()方法等待事件被设置,通过set()方法设置事件,从而唤醒等待事件的线程。

2.4 条件(Condition)

条件是一种复杂的线程同步机制,它可以让线程在特定条件下等待或唤醒。在Python中,可以使用threading.Condition类来创建条件对象,并通过wait()、notify()和notify_all()方法来实现线程的等待和唤醒。

import threadingcondition = threading.Condition()def wait_for_condition():with condition:condition.wait() # 等待条件# 处理条件def set_condition():with condition:condition.notify() # 唤醒等待条件的线程

在上面的示例中,我们创建了一个条件对象condition,线程可以通过wait()方法等待条件,通过notify()方法唤醒等待条件的线程。

3. 线程优先级队列(Queue)

在Python中,线程优先级队列(Priority Queue)是一种特殊的队列,它可以根据元素的优先级来确定元素的顺序。在标准的队列中,元素是按照先进先出(FIFO)的顺序进行排列的,而在优先级队列中,元素的顺序是根据其优先级来确定的,优先级高的元素会被优先处理。Python中的线程优先级队列通常使用queue.PriorityQueue类来实现,它是线程安全的队列,可以在多线程环境中安全地进行操作。
Queue 模块中的常用方法:

  • Queue.qsize() 返回队列的大小
  • Queue.empty() 如果队列为空,返回True,反之False
  • Queue.full() 如果队列满了,返回True,反之False
  • Queue.full 与 maxsize 大小对应
  • Queue.get([block[, timeout]])获取队列,timeout等待时间
  • Queue.get_nowait() 相当Queue.get(False)
  • Queue.put(item) 写入队列,timeout等待时间
  • Queue.put_nowait(item) 相当Queue.put(item, False)
  • Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
  • Queue.join() 实际上意味着等到队列为空,再执行别的操作
import queue
import threading
import timedef process_task(priority_queue):while True:priority, data = priority_queue.get()print(f'Processing task: {data}, Priority: {priority}')priority_queue.task_done()priority_queue = queue.PriorityQueue()# 启动处理任务的线程
thread = threading.Thread(target=process_task, args=(priority_queue,))
thread.start()# 插入任务到优先级队列
priority_queue.put((2, 'Task 1'))
priority_queue.put((1, 'Task 2'))
priority_queue.put((3, 'Task 3'))# 等待所有任务处理完成
priority_queue.join()

在上面的示例中,我们创建了一个优先级队列priority_queue,并启动了一个线程来处理任务。然后向优先级队列中插入了三个任务,并通过join()方法等待所有任务处理完成。

总结

本文详细讲解了Python3中的多线程编程,包括线程的创建、同步、优先级队列等内容。通过合理地使用多线程技术,可以提高程序的执行效率,实现并发处理任务。

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

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

相关文章

【Linux】Centos9设置ActiveMq开机自启功能

配置流程: 1. 创建 Systemd 服务文件。这个文件通常存放在/usr/lib/systemd/system/目录下,命名为 activemq.service。 #先创建文件,然后编辑: sudo touch /usr/lib/systemd/system/activemq.service sudo vim /usr/lib/systemd…

CSS 根据子元素选择父元素,并设置父元素的样式

场景举例&#xff1a;当子元素有增加了一个class时&#xff0c;需要影响其父元素的样式 可以使用":has"伪类来实现选择父元素的效果 <style>.parent:has(.child){background-color: #eee;}p{width:100px;border:1px solid #000;} </style> <body>…

Python3 笔记:for语句和while语句的区别

一般来说&#xff0c;循环次数确定的问题使用for循环或者while循环都可以解决&#xff0c;而循环次数不确定的问题只能使用while循环解决。 for语句的格式&#xff1a; for 循环变量 in 遍历对象: 语句 while语句的格式&#xff1a; while 条件表达式: 循环体 for…

人机协同中的比较、调整与反转

人机协同是指人与机器之间的合作关系&#xff0c;通过共同努力实现特定任务的目标。在人机协同中&#xff0c;存在着比较与调整的过程&#xff0c;这是为了实现更好的合作效果和任务完成质量。 比较是指人与机器在任务执行过程中对彼此的表现进行评估和比较。这可以通过对机器的…

DB类的学习

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data; //引用三个命名空间 using System.Data.SqlClient; using System.Configuration;/// <summary> /// DB 的摘要说明 /// </summary> public class DB {p…

vue+ts+vite+pinia+less+echarts 前端可视化 实战项目

1.初始化前端 输入 npm init vuelatest 命令 然后 选择需要的插件2.构建完成后 在终端切换到vue-project文件夹下 npm install 下载依赖 3.下载 less样式 npm install less less-loader -D 4.下载axios npm install axios 5.下载echarts npm install echarts -S 6.引入中国…

JAVA 的数据类型

Java 是一种静态类型语言&#xff0c;这意味着在编译时&#xff0c;变量必须声明其数据类型。在 Java 中&#xff0c;数据类型可以分为两大类&#xff1a;基本数据类型&#xff08;又称原始数据类型&#xff09;和引用数据类型。本文将详细介绍这两种数据类型。 一、基本数据类…

战网国际服加速器用哪个好 暴雪战网好用加速器介绍

战网国际版&#xff0c;又称Battle.net环球版&#xff0c;是暴雪娱乐操盘的全球性游戏互动平台&#xff0c;它跨越地理界限&#xff0c;服务于全球游戏爱好者。与地区限定版本相异&#xff0c;国际版赋予玩家自由进入暴雪旗下众多经典游戏的权利&#xff0c;无论身处何方&#…

对比测评3款BI分析工具

前不久&#xff0c;一位准备入职阿里的学弟问我&#xff0c;他要做电商数据分析&#xff0c;电商有庞杂的标签、模型、数据和业务逻辑&#xff0c;菜鸟应该要具备什么样的分析能力啊&#xff1f; 我看了他的岗位职责&#xff0c;主要是负责经营决策支持、专题分析和数据看板搭…

leetcode-字符串变形-104

题目要求 思路 1.首先根据ASCII的规则&#xff0c;把字符串大小写替换&#xff0c;空格保持不变 2.将整个字符串进行翻转 3.以空格为区间&#xff0c;将区间内的字符串进行翻转&#xff0c;其中翻转的函数reverse() 代码实现 class Solution { public:string trans(string s…

【C语言】通讯录系统实现

目录 1、通讯录系统介绍 2、代码分装 3、代码实现步骤 3.1制作菜单函数以及游戏运行逻辑流程 3.2、封装人的信息PeoInfo以及通讯录Contact结构体类型 3.3、初始化通讯录InitContact函数 3.4、增加联系人AddContact函数 3.5、显示所有联系人ShowContact函数 3.6、删除联系人D…

Shell之常用命令

目录 1.排序工具--sort命令 1.1 快读查找一个目录中最大文件 2.去重工具--uniq命令 2.1 分析判断远程登录错误次数&#xff0c;禁止该用户远程登录 3.修改工具--tr命令 4.列截取工具--cut命令 5.分割文件工具--split命令 6.合并文件列--paste命令 7.扫描工具--eval命令…

OpenAI和互联网行业的发展,有着异曲同工之处

当OpenAI首席技术官米拉穆拉提发布桌面版本的ChatGPT和新的旗舰模型—GPT-4o&#xff0c;OpenAI的发展&#xff0c;进入到了一个真正意义上的奇点时刻。 OpenAI的短短26分钟的发布会&#xff0c;却依然引发了不少波澜。 无论是ChatGPT-4o的完全免费&#xff0c;抑或是推出PC桌…

【Linux】常用指令、热键与权限管理

一、常用指令 &#xff08;1&#xff09;ls 功能&#xff1a;列出指定目录下的所有子目录与文件 用法&#xff1a;ls &#xff08;选项&#xff09; &#xff08;目录或文件名&#xff09; 常用选项&#xff1a; -a&#xff1a;列出目录下的所有文件&#xff0c;包括隐藏…

c语言中数字字符串和数字互转

#include <getopt.h> #include <stdio.h> #include <stdlib.h>#define MAX_PATH 256 char filename[MAX_PATH 5]; int main(int argc, char** argv) {//数字字符串转数字const char* kk "689";int zhi atoi(kk) 8;//数字字符串转doubledoub…

从HTTP迁移到HTTPS:一篇全面的测试方案设计指南

在当今的互联网世界里&#xff0c;数据安全性日益受到重视。将网站从HTTP迁移到HTTPS已成为提升数据传输安全性的重要一步。HTTPS&#xff08;超文本传输安全协议&#xff09;通过SSL/TLS协议为客户端和服务器之间的通信加密&#xff0c;保护数据免受中间人攻击&#xff08;MIT…

代码随想录训练营Day 29|力扣39. 组合总和、40.组合总和II、131.分割回文串

1.组合总和 题目链接/文章讲解&#xff1a; 代码随想录 视频讲解&#xff1a;带你学透回溯算法-组合总和&#xff08;对应「leetcode」力扣题目&#xff1a;39.组合总和&#xff09;| 回溯法精讲&#xff01;_哔哩哔哩_bilibili 代码&#xff1a;&#xff08;未剪枝版 &#xf…

ChatGPT未来可能应用于iPhone?

苹果接即将与OpenAI达成协议 ChatGPT未来应用于iPhone 前言 就在5月11日&#xff0c;苹果公司正与OpenAI进行深入讨论&#xff0c;计划在其最新的iOS操作系统中整合OpenAI的先进技术。这一举措是苹果公司在为其产品线融入更先进的人工智能功能所做努力的一部分。 目前情况双方…

vue2 八大组件通信,父子通信,跨层级通信,事件总线,vuex等

文章目录 什么是组件通信&#xff1f;父子通信流程propsProps 定义Props 作用特点数组写法对象写法&#xff08;props校验&#xff09;简写只验证数据类型&#xff1a;完整写法&#xff0c;完整的验证&#xff1a; props父向子传值用props父传子在子组件中修改props $emit子向父…

自定义 Gradle 插件进行统一的静态代码分析

静态代码分析是一项了不起的技术, 它能让代码库更易于维护. 但是, 如果你在不同的版本库中拥有多个服务(可能由不同的团队开发), 如何才能让每个人都遵循既定的代码风格呢? 一个好办法是将所有规则封装在一个插件中, 该插件会在每个项目构建时自动执行所需的验证. 因此, 在本…