07 Python进阶:多线程

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,它会按照元素的优先级进行排序。然后,我们创建了两个线程分别向队列中添加元素,并创建一个线程来从队列中获取元素。

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

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

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

StarRocks实战——华米科技埋点分析平台建设

目录 前言 一、原有方案及其痛点 二、引入StarRocks 三、方案改造 3.1 架构设计 3.2 数据流程 3.3 性能指标 3.4 改造收益 前言 华米科技是一家基于云的健康服务提供商,每天都会有海量的埋点数据,以往基于HBase建设的埋点计算分析项目往往效率上…

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

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

Linux | MySQL安装Workbench图形化

环境:rhel8 MySQL8 下载软件包 官网软件包地址: MySQL :: 下载 MySQL Workbenchhttps://dev.mysql.com/downloads/workbench/我这里下载的是 mysql-workbench-community-8.0.24-1.el8.x86_64.rpm 解决依赖 用rpm安装发现缺少依赖 [rooth…

3dmax经常染失败?优化方法提升染质量!

在三维建模和渲染的过程中,优化模型和场景的效率是至关重要的。以下是一些提升效率的方法: 模型简化:在创建模型时,应尽量减少使用的命令和修改器的数量。这是因为命令和修改器越多,消耗的内存和CPU资源也就越多&…

FJSP:巨型犰狳优化算法(Giant Armadillo Optimization,GAO)求解柔性作业车间调度问题(FJSP),提供MATLAB代码

一、柔性作业车间调度问题 柔性作业车间调度问题(Flexible Job Shop Scheduling Problem,FJSP),是一种经典的组合优化问题。在FJSP问题中,有多个作业需要在多个机器上进行加工,每个作业由一系列工序组成&a…

大米自动化生产线设备:现代粮食加工的核心力量

随着科技的不断进步和粮食加工行业的快速发展,大米自动化生产线设备在现代粮食加工中的地位愈发重要。这些设备不仅大大提高了生产效率,还保证了产品的质量和安全,成为了现代粮食加工行业不可或缺的核心力量。 一、自动化生产线设备助力效率提…

达托机器人(DRB)平台的安全性和前景是否可靠?

在当今数字化时代,技术创新不仅是企业成功的关键,也是整个行业的驱动力。在这个背景下,达托机器人(DRB)脱颖而出,以其创世团队的坚实基础和平台的可靠前景,引起了业界的广泛关注。 首先&#xf…

消息队列MQ(面试题:为什么使用MQ)

一、什么是mq? MQ全称 Message Queue(消息队列),是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信,解耦。 二、常见的mq产品 RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq RabbitMQ: One broker …

人工智能、深度伪造和数字身份:企业网络安全的新前沿

深度伪造(Deepfakes)的出现打响了网络安全军备竞赛的发令枪。对其影响的偏执已经波及到一系列领域,包括政治错误信息、假新闻和社交媒体操纵。 深度伪造将加剧公共领域对信任和沟通的本已严峻的压力。这将理所当然地引起监管机构和政策制定者…

java.lang.NoClassDefFoundError: javax/validation/constraints/Min

1、报错截图 2、解决办法 添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId> </dependency>

浮点数在内存中的存储【详解】

浮点数在内存中的存储 浮点数存储规则小数点后数值的二进制转换float和double存储图示优化存储方案E不全为0或不全为1E全为0E全为1 浮点数存储规则 大家都知道整型数据是以补码的方式存放在内存中。以下几个概念是需要知道的&#xff1a; 原码&#xff0c;补码&#xff0c;反…

C++入门语法(命名空间缺省函数函数重载引用内联函数nullptr)

目录 前言 1. 什么是C 2. C关键字 3. 命名空间 3.1 命名空间的定义 3.2 命名空间的使用 4. C输入和输出 5. 缺省函数 5.1 概念 5.2 缺省参数分类 6. 函数重载 6.1 概念 6.2 为何C支持函数重载 7. 引用 7.1 概念 7.2 特性 7.3 常引用 7.4 引用与指针的区别 7…

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…

人工智能 - 服务于谁?

人工智能服务于谁&#xff1f; 人工智能服务于生存&#xff0c;其最终就是服务于战争&#xff08;热战、技术战、经济战&#xff09; 反正就是为了活着而战的决策。 既然人工智能所有结果&#xff0c;来自大数据的分挖掘&#xff08;分析&#xff09;也就是数据的应用&#x…

施耐德中高端PLC仿真器

参考文档&#xff1a;《Unity Pro PLC 仿真器》EIO0000001719.06 &#xff08;Control Expert 就是 Unity Pro 最新版本换了个名字&#xff0c;两者操作基本相同&#xff09; https://www.schneider-electric.cn/zh/download/document/EIO0000001719/ 1. 适用 PLC 这里使用的…

idea常用配置

IDEA设置全局配置 参考&#xff1a;IDEA设置全局配置_idea如何打开一个项目,全局设置-CSDN博客 idea提交代码到git或svn上时&#xff0c;怎么忽略.class、.iml文件和文件夹等不必要的文件 参考&#xff1a;idea提交代码到git或svn上时&#xff0c;怎么忽略.class、.iml文件和文…

【Frida】【Android】 工具篇:查壳工具大赏

&#x1f6eb; 系列文章导航 【Frida】【Android】01_手把手教你环境搭建 https://blog.csdn.net/kinghzking/article/details/136986950【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446【Frida】【Android】03_RPC https://bl…

MIT6.828 Lab1 Xv6 and Unix utilities

2023MIT6.828 lab-1 官方地址 一、sleep 实验内容 调用sleep&#xff08;系统调用&#xff09;编写用户级别程序能暂停特定时常的系统滴答程序保存在user/sleep.c 实验过程 xv6的参数传递 查看官方文档提示的文件中&#xff0c;多采用如下定义&#xff1a; int main(in…

window安装maven和hadoop3.1.4

前面的文章已讲解如何安装idea和进行基本设置&#xff0c;本文主要带着大家安装配置好maven和hadoop. 大家不用去官网下载&#xff0c;直接使用我发给大家的压缩文件&#xff0c;注意解压后的文件夹不要放在中文目录下&#xff0c;课堂上我们讲解过原因。 这是我电脑上的路径&a…

#QT项目实战(天气预报)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a; 3.记录&#xff1a; &#xff08;1&#xff09;调用API的Url a.调用API获取IP whois.pconline.com.cn/ipJson.jsp?iphttp://whois.pconline.com.cn/ipJson.jsp?ip if(window.IPCallBack) {IPCallBack({"ip":&quo…