07 Python进阶:多线程

news2024/12/25 13:56:01

python线程概念

在这里插入图片描述

在 Python 中,线程(Thread)是用于实现多任务并发执行的基本单元。线程允许程序同时执行多个部分,每个部分称为一个线程,因此能够提高程序的效率,特别适用于需要同时执行多个任务的情况。下面是关于 Python 线程的一些基本概念:

  1. 线程概念

    • 线程是操作系统能够进行运算调度的最小单位,即程序中的一个执行流。
    • 每个进程至少包含一个线程,即主线程,通过创建更多的线程可以实现多线程并发执行。
  2. Python 中线程模块

    • Python内置了threading模块,可以方便地创建和管理线程。
    • threading.Thread类用于表示线程对象,通过继承threading.Thread类并重写run()方法来定义线程执行的任务。
  3. 线程的创建

    • 通过实例化threading.Thread类,并指定target参数为线程执行的函数,然后调用start()方法启动线程。
    • 也可以直接使用函数式风格创建线程,例如thread = threading.Thread(target=my_function)
  4. 线程的生命周期

    • 新建状态(New):线程对象被创建但尚未启动。
    • 就绪状态(Runnable):线程处于就绪队列中等待获取CPU时间片。
    • 运行状态(Running):线程占用CPU资源执行任务。
    • 阻塞状态(Blocked):线程等待某个条件满足而无法继续执行。
    • 终止状态(Terminated):线程任务执行结束或者出现异常终止。
  5. 线程同步

    • 在多线程环境下,可能存在共享资源的竞争问题,使用锁、条件变量等工具进行线程间同步操作,避免数据竞争问题。
  6. 线程间通信

    • 可以使用队列(Queue)、事件(Event)、信号量(Semaphore)等机制进行线程间的消息传递和同步操作。
  7. 常见的线程问题

    • 竞态条件(Race Condition):多个线程竞争对共享资源进行读写时可能导致数据不一致。
    • 死锁(Deadlock):两个或多个线程无限期地等待对方持有的资源,导致所有线程无法继续执行。

线程是一种轻量级的执行单元,在 Python 中可以很方便地进行线程编程,但要注意线程安全、同步和通信等问题,以保证多线程程序的正确性和稳定性。

Python多线程概念

在Python中,可以使用多线程来实现并发执行多个任务。与单线程相比,多线程可以让程序同时执行多个子任务,从而提高程序的执行效率。以下是关于Python多线程的一些重要概念:

  1. GIL(全局解释器锁)

    • 在 CPython 解释器中,由于 GIL 的存在,同一时刻只能有一个线程在解释器中执行 Python 字节码,这意味着多线程并不能真正实现并行执行。
    • GIL 是为了保护解释器内部数据结构不被破坏,在 CPU 密集型任务中可能会成为性能瓶颈。
  2. threading 模块

    • Python 的标准库中提供了threading模块,用于支持多线程编程。
    • 使用threading.Thread类可以创建线程对象,通过调用start()方法启动线程。
  3. 线程的创建和启动

    • 通过创建threading.Thread的实例,并设定target参数为线程要执行的函数或方法。
    • 然后调用 start() 方法启动线程,线程会进入就绪状态,等待获取CPU时间片执行任务。
  4. 线程的同步和互斥

    • 在多线程编程中,可能存在共享数据的情况,需要使用锁(Lock)、信号量(Semaphore)、条件变量(Condition)等机制来保证数据的安全访问。
    • 同步工具能够协调多个线程之间的行为,确保线程安全地访问共享资源。
  5. 线程间通信

    • 线程间通信是指不同线程之间传递数据或控制信息的过程。Python 中可以使用队列(Queue)来实现线程间安全的通信。
  6. 线程池

    • 线程池是一种线程管理机制,可以提前创建一组线程,并将任务分配给这些线程来执行,减少线程创建和销毁的开销。
    • Python 中可以使用 concurrent.futures 模块提供的线程池来管理线程执行。

虽然 Python 中的 GIL 限制了多线程并行执行的能力,但对于 I/O 密集型任务或需要同时处理多个任务的情况,多线程仍然是一种有效的并发编程方式。在使用多线程时,要注意线程安全、同步和通信,以避免出现数据竞争和其他问题。

希望以上解释对您有所帮助。如果您有任何疑问或需要更多信息,请随时告诉我。

线程模块

在Python中,threading 模块提供了用于多线程编程的工具。threading 模块允许开发者创建和管理线程,实现并发执行多个任务。下面是对 threading 模块的一些重要组成部分的详细介绍以及一个简单的示例:

  1. Thread 类
    • threading.Thread 类是用来表示线程的类。
    • 通过创建 threading.Thread 类的实例并传入 target 参数指定线程执行的函数或方法,然后调用 start() 方法启动线程。
import threading

# 线程执行的函数
def task():
    print("Thread Function.")

# 创建线程对象
thread = threading.Thread(target=task)

# 启动线程
thread.start()
  1. Lock 类
    • threading.Lock 类提供了简单的锁机制,用于确保在多个线程中只有一个线程能够访问共享资源。
import threading

# 创建锁
lock = threading.Lock()

# 线程执行的函数
def task():
    lock.acquire()  # 获取锁
    print("Thread Function.")
    lock.release()  # 释放锁

# 创建线程对象
thread1 = threading.Thread(target=task)
thread2 = threading.Thread(target=task)

# 启动线程
thread1.start()
thread2.start()
  1. Semaphore 类
    • threading.Semaphore 类是信号量,通常用于控制同时访问某个共享资源的最大线程数。
import threading

# 创建信号量,设置最大并发数为2
semaphore = threading.Semaphore(2)

# 线程执行的函数
def task():
    with semaphore:
        print("Thread Function.")

# 创建线程对象
thread1 = threading.Thread(target=task)
thread2 = threading.Thread(target=task)
thread3 = threading.Thread(target=task)

# 启动线程
thread1.start()
thread2.start()
thread3.start()
  1. Condition 类
    • threading.Condition 类通过调用 wait()notify()notify_all() 方法实现线程间的协调和通信。
import threading

# 创建 Condition 对象
condition = threading.Condition()

# 线程执行的函数
def producer():
    with condition:
        print("Producer producing an item.")
        condition.notify()

def consumer():
    with condition:
        condition.wait()
        print("Consumer consuming the item.")

# 创建线程对象
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)

# 启动线程
producer_thread.start()
consumer_thread.start()

以上是 threading 模块中一些重要类的使用示例。通过合理地利用这些类,可以实现多线程编程中的同步、互斥和线程间通信等功能。

使用 threading 模块创建线程

使用 Python 的 threading 模块可以很容易地创建和管理线程。下面是使用 threading 模块创建线程的简单示例:

import threading

# 定义一个线程执行的函数
def print_numbers():
    for i in range(1, 6):
        print(i)

# 创建线程对象
t1 = threading.Thread(target=print_numbers)

# 启动线程
t1.start()

# 主线程可以继续执行其他操作
print("Main thread continues to run.")

在这个示例中,我们首先定义了一个函数 print_numbers,它会打印数字 1 到 5。然后,我们使用 threading.Thread 类创建了一个名为 t1 的线程对象,并将 print_numbers 函数作为目标函数传递给该线程对象。最后,我们通过调用 start() 方法启动了线程 t1

一旦线程被启动,它就会开始执行目标函数,而主线程也可以继续执行其他操作。通过这种方式,我们可以创建并发执行的多个任务,实现程序中的并行处理。

线程同步

在这里插入图片描述

线程同步是指多个线程按照一定的协调顺序来访问共享资源,以确保线程之间不会发生数据竞争和冲突。常见的线程同步机制包括锁(Locks)、条件变量(Condition Variables)、信号量(Semaphores)等。这些机制可以帮助线程互相协调,避免数据污染和不确定的行为。

线程同步通常涉及以下几种情况:

  1. 保护共享资源:多个线程如果要访问共享的数据或资源,需要通过线程同步机制来确保在任意时刻只有一个线程能够访问该资源,例如使用锁机制来实现互斥访问。

  2. 协调线程之间的交互:有时候需要线程之间按照一定的顺序进行交互,例如生产者-消费者模型中生产者需要等待直到缓冲区不再满,这时可以使用条件变量来实现线程间的协调。

  3. 控制并发数量:某些场景下需要限制同时执行的线程数量,以避免资源过度竞争或者提供限流功能,这时可以使用信号量来控制并发数量。

线程同步是多线程编程中非常重要的概念,它能够帮助我们避免诸如死锁、饥饿、竞态条件等问题,保证程序的正确性和可靠性。

示例中,我们将使用锁(Lock)来保护共享资源,确保多个线程安全地访问该资源。

import threading

# 共享资源
shared_resource = 0
lock = threading.Lock()

# 线程函数:增加共享资源的值
def increment_shared_resource():
    global shared_resource
    with lock:
        for _ in range(10000):
            shared_resource += 1

# 创建多个线程来增加共享资源的值
threads = []
for _ in range(5):
    t = threading.Thread(target=increment_shared_resource)
    threads.append(t)
    t.start()

# 等待所有线程执行完毕
for t in threads:
    t.join()

# 打印最终的共享资源的值
print("Final value of shared resource:", shared_resource)

在这个示例中,我们定义了一个共享变量 shared_resource 为 0,并创建了一个全局的锁 lockincrement_shared_resource 函数会使用锁来保护对 shared_resource 的增加操作,确保同一时刻只有一个线程可以修改该共享资源。

然后,我们创建了5个线程来调用 increment_shared_resource 函数,每个线程将共享资源增加10000次。通过锁的机制,我们确保这些线程可以安全地访问和修改共享资源。

最后,我们等待所有线程执行完毕,输出最终的共享资源值。此示例展示了如何利用锁来实现线程同步,保护共享资源的并发访问,避免数据竞争问题。

线程优先级队列( Queue)

线程优先级队列(Priority Queue)是一种特殊类型的队列,其中每个元素都有一个与之相关联的优先级。在 Python 中,可以使用 queue.PriorityQueue 类来实现线程安全的优先级队列,这在多线程编程中非常有用。

下面是一个简单的示例,演示如何使用 queue.PriorityQueue 创建线程安全的优先级队列:

import queue
import threading

# 创建优先级队列
priority_queue = queue.PriorityQueue()

# 线程函数:向队列中添加元素
def add_item(item, priority):
    priority_queue.put((priority, item))

# 线程函数:从队列中获取元素
def get_item():
    while True:
        item = priority_queue.get()
        print("Got item:", item)
        priority_queue.task_done()

# 创建线程来向队列中添加元素
threading.Thread(target=add_item, args=("Item 1", 3)).start()
threading.Thread(target=add_item, args=("Item 2", 1)).start()

# 创建线程来从队列中获取元素
t = threading.Thread(target=get_item)
t.start()
t.join()

# 等待所有元素被处理完毋
priority_queue.join()

在这个示例中,我们首先创建了一个 queue.PriorityQueue 实例 priority_queue,它会按照元素的优先级进行排序。然后,我们创建了两个线程分别向队列中添加元素,并创建一个线程来从队列中获取元素。

通过使用优先级队列,可以确保高优先级的元素先被获取,非常适用于需要按照特定顺序处理任务的场景。在多线程编程中,线程安全的优先级队列可以帮助我们更好地组织和协调线程间的操作,提高程序的效率和可靠性。

关注我,不迷路,共学习,同进步

关注我,不迷路,共学习,同进步

在这里插入图片描述

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

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

相关文章

docker-compose安装dozzle

dozzle是一个docker日志的webui工具 安装配置 docker-compose.yaml version: "3" services:dozzle:container_name: dozzleimage: amir20/dozzle:v4.11.4volumes:- /var/run/docker.sock:/var/run/docker.sockrestart: unless-stoppedports:- 20342:8080networks:cu…

HarmonyOS4.0 ArkUI常用组件

一、Image 语法: Image(src:string|PixelMap|Resource)使用方式: string格式:用来加载网络图片,需要在module.json5中申请网络访问权限:ohos.permission.INTERNET Image("http://xxx.png")PixelMap格式&am…

Windows11安装MySql-8.0.36安装详细教程(保姆级教程)

之前一直用的mysql5.7,最近导入一个项目一直报错,经查阅发现数据库mysql版本太老,今天特地重头下载安装配置一下,做个记录供大家参考。 下载安装包: 下载地址:https://dev.mysql.com/downloads/ 进入后选…

如何在WHM面板上创建cPanel账户

本周有一个客户,购买Hostease的独立服务器并选择了WHM控制面板,询问我们的在线客服,如何在WHM面板上创建cPanel账户。我们为用户提供教程,用户很快完成了设置。在此,我们分享这个操作教程,希望可以对您有帮…

使用Springboot配置生产者、消费者RabbitMQ?

生产者服务 1、引入依赖以及配置rabbitmq 此时我们通过使用springboot来快速搭建一个生产者服务 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency> applica…

智慧数字乡村解决方案大全:标准规范顶层设计指南、供应商整体解决方案及售前PPT、数字乡村标准白皮书等全套460份,一次性打包下载

关键词&#xff1a;数字乡村解决方案&#xff0c;数字乡村标准白皮书&#xff0c;数字乡村建设成功案例&#xff0c;数字乡村发展行动计划&#xff0c;数字乡村建设方案&#xff0c;数字乡村云平台&#xff0c;数字乡村建设指南&#xff0c;智慧乡村建设解决方案&#xff0c;智…

【游戏分析】非游戏领空追字符串来源

通过NPC名称找NPC数组 扫描 NPC名字 ASIC型 发现全部都有后缀 那么采用 字节集的方式去扫描 也是扫不到 说明:不是ASIC型字符串 扫描 NPC名字 Unicode型 没有结果 那么转换成字节集去扫描 终于发现结果了 把结果挨个修改字符串 发现 其中两个是可以用的 22和23 …

什么是超导悬浮?工作原理是什么?

某些材料在冷却到某个温度&#xff08;也称为“临界温度”&#xff09;以下时会完全失去电阻。 1910 年&#xff0c;一位名叫 Heike Kamerlingh Onnes 的荷兰物理学家发现了这一现象。他注意到低于一定温度时电阻突然下降&#xff0c;然后他大胆地声称发现了一种新的物质状态&a…

C++ 【桥接模式】

简单介绍 桥接模式属于 结构型模式 | 可将一个大类或一系列紧密相关的类拆分 为抽象和实现两个独立的层次结构&#xff0c; 从而能在开发时分别使用。 聚合关系&#xff1a;两个类处于不同的层次&#xff0c;强调了一个整体/局部的关系,当汽车对象销毁时&#xff0c;轮胎对象…

觉醒的力量!即使S3,我们应该积极应对,而不是抱怨——早读(逆天打工人爬取热门微信文章解读)

即使S3&#xff0c;我们应该积极应对&#xff0c;而不是抱怨 引言Python 代码第一篇 洞见 觉醒的力量&#xff08;深度好文&#xff09;第二篇 人民日报 来了&#xff01;新闻早班车要闻社会政策 结尾 引言 横眉冷对千夫指&#xff0c;俯首甘为孺子牛 今天迸发出这样的一句话 …

Unity 使用 IL2CPP 发布项目

一、为什么用 IL2CPP Unity的IL2CPP&#xff08;Intermediate Language to C&#xff09;是一个编译技术&#xff0c;它将C#代码转换为C代码&#xff0c;然后再编译成平台相关的二进制代码。IL2CPP提供了几个优点&#xff0c;特别是在性能和跨平台部署方面。以下是IL2CPP的一些…

UI自动化框架搭建以及面试题详解(上)

UI自动化框架搭建以及面试题 UI自动化面试题框架面试题那你讲下如何搭建现成的框架公司里面的框架是你搭建的么请结合你的项目讲解一下你的框架是如何搭建的 PO模式什么是 PO 模式PO 模式的封装原则有哪些 DDT驱动模式什么的项目适合ddt ddt四种模式ddt处理各种类型数据 自动化…

完成产品兼容互认,用KubeBlocks可实现OceanBase集群管理

本文转载自云猿生聊技术&#xff08;CloudNativeDataTech&#xff09; 前言 KubeBlocks&#xff08;简称 KB&#xff09;在最新发布的0.7版本中&#xff0c;通过组件扩展&#xff08;Addon&#xff09;的形式新增了对OceanBase的支持功能。这一更新为企业级和非企业级用户提供…

摄影杂记一

摄影小白&#xff0c;最近买了一台微单&#xff0c;型号是佳能R10&#xff0c;加上18-150套机镜头和佳能RF 50 F1.8定焦镜头。开始学习摄影。 PS&#xff1a;摄影穷三代&#xff0c;单反毁一生。嘿嘿。 一、分镜头拍摄四步提升法 B站&#xff1a;六斤 拍视频三件事&#xff1…

线程池CompletableFuture异步编排复习笔记

一、线程回顾 1.1 初始化线程的 4 种方式 1&#xff09;、继承 Thread public static class Thread01 extends Thread {Overridepublic void run() {System.out.println("当前线程&#xff1a;" Thread.currentThread().getId());int i 10 / 2;System.out.print…

十分钟搞定TCP三次握手面试

三次握手过程 1.客户端与客户端都处于close状态&#xff0c;服务器主动对某端口进行监听后处于LISTEN状态 2.客户端将SYN标志位置为1&#xff0c;向服务器发,SYN和初始序列号seq后处于SYN_SENT状态 2.服务器处于LISTEN状态&#xff0c;收到客户端发来的请求后将SYN和ACK的标志…

基于DCT和扩频的音频水印嵌入提取算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ......................................................................... N 10; %嵌入一…

ubuntu安装编程字体DejaVu Sans Mono

DejaVu Sans Mono 安装命令&#xff1a; sudo apt-get install ttf-dejavu

唐刘:关于产品质量的思考 - 如何评估质量

在上一篇文章《 关于产品质量的思考 - 我的基本认知 》中&#xff0c;作者通过亲身经历分享了对产品质量的思考和认知&#xff1a;高质量的产品不仅仅是通过测试来保证的&#xff0c;更是通过在真实场景中不断打磨和改进得来的。本文为“关于产品质量的思考”系列的第二篇&…

2024.4.2-day07-CSS 盒子模型(显示模式、盒子模型)

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 作业 2024.4.2 学习笔记CSS标签元素显示模式1 块元素2 行内元素3 行内块元素4…