【Python】教你彻底了解Python中的并发编程

​​​​在这里插入图片描述

文章目录

    • 一、并发编程的基本概念
      • 1. 线程(Thread)
      • 2. 进程(Process)
      • 3. 协程(Coroutine)
    • 二、Python中的线程与进程
      • 1. 线程
        • 1.1 创建和启动线程
        • 1.2 线程同步
      • 2. 多进程
        • 2.1 创建和启动进程
        • 2.2 进程间通信
    • 三、异步编程
      • 1. 协程
        • 1.1 定义和调用协程
      • 2. 异步任务
    • 四、并发编程的实际应用示例
      • 1. 多线程Web爬虫
      • 2. 多进程图像处理
    • 五、并发编程的注意事项
      • 1. 线程安全
      • 2. 死锁
      • 3. 资源消耗
      • 4. 异常处理
    • 结论

随着计算机处理能力的不断提升和多核处理器的普及,并发编程变得越来越重要。并发编程可以使程序同时执行多个任务,从而提高程序的性能和响应速度。在Python中,有多种方式可以实现并发编程,包括线程、进程和异步编程。在这篇文章中,我们将深入探讨Python中的并发编程,涵盖其基本概念、线程与进程、多线程编程、多进程编程、异步编程以及并发编程的实际应用示例。

一、并发编程的基本概念

并发编程是指同时执行多个任务的编程技术。并发编程的目标是提高程序的执行效率和响应速度。在并发编程中,有几个重要的概念需要理解:

1. 线程(Thread)

线程是程序执行的最小单位。一个进程可以包含多个线程,每个线程可以执行不同的任务。线程之间可以共享内存,因此线程之间的通信比较容易,但需要注意线程安全问题。

2. 进程(Process)

进程是程序执行的一个实例。每个进程有自己独立的内存空间,相互之间不会影响。多进程编程可以有效利用多核处理器,但进程之间的通信相对复杂。

3. 协程(Coroutine)

协程是一种比线程更轻量级的并发实现方式。协程在执行过程中可以暂停和恢复,从而实现非阻塞的并发执行。Python中的异步编程通常使用协程来实现。

二、Python中的线程与进程

Python中提供了多种实现并发编程的方式,包括线程、多进程和异步编程。我们将分别介绍这些方法,并讨论它们的优缺点。

1. 线程

Python中的threading模块提供了创建和管理线程的功能。通过threading.Thread类,我们可以创建和启动线程。

1.1 创建和启动线程

以下示例展示了如何创建和启动线程:

import threading

def print_numbers():
    for i in range(1, 6):
        print(i)

# 创建线程
thread = threading.Thread(target=print_numbers)

# 启动线程
thread.start()

# 等待线程结束
thread.join()
print("Thread execution completed.")

在上面的例子中,我们创建了一个线程来执行print_numbers函数,并启动了线程。join方法用于等待线程执行完成。

1.2 线程同步

在多线程编程中,多个线程可能会同时访问共享资源,从而导致数据不一致的问题。为了避免这种情况,我们可以使用线程同步机制,如锁(Lock)。

以下示例展示了如何使用锁来同步线程:

import threading

counter = 0
lock = threading.Lock()

def increment_counter():
    global counter
    for _ in range(1000000):
        with lock:
            counter += 1

# 创建和启动线程
threads = []
for _ in range(5):
    thread = threading.Thread(target=increment_counter)
    threads.append(thread)
    thread.start()

# 等待所有线程结束
for thread in threads:
    thread.join()

print(f"Final counter value: {counter}")

在上面的例子中,我们使用锁来确保每次只有一个线程可以访问和修改counter变量,从而避免数据不一致的问题。

2. 多进程

Python中的multiprocessing模块提供了创建和管理进程的功能。多进程编程可以有效利用多核处理器,提高程序的执行效率。

2.1 创建和启动进程

以下示例展示了如何创建和启动进程:

import multiprocessing

def print_numbers():
    for i in range(1, 6):
        print(i)

# 创建进程
process = multiprocessing.Process(target=print_numbers)

# 启动进程
process.start()

# 等待进程结束
process.join()
print("Process execution completed.")

在上面的例子中,我们创建了一个进程来执行print_numbers函数,并启动了进程。join方法用于等待进程执行完成。

2.2 进程间通信

进程之间有独立的内存空间,因此进程间通信相对复杂。Python的multiprocessing模块提供了多种进程间通信的机制,如队列(Queue)和管道(Pipe)。

以下示例展示了如何使用队列进行进程间通信:

import multiprocessing

def producer(queue):
    for i in range(5):
        queue.put(i)
        print(f"Produced: {i}")

def consumer(queue):
    while True:
        item = queue.get()
        if item is None:
            break
        print(f"Consumed: {item}")

# 创建队列
queue = multiprocessing.Queue()

# 创建和启动生产者和消费者进程
producer_process = multiprocessing.Process(target=producer, args=(queue,))
consumer_process = multiprocessing.Process(target=consumer, args=(queue,))

producer_process.start()
consumer_process.start()

# 等待生产者进程结束
producer_process.join()

# 发送终止信号给消费者进程
queue.put(None)

# 等待消费者进程结束
consumer_process.join()
print("Producer and Consumer execution completed.")

在上面的例子中,我们使用队列来在生产者和消费者进程之间传递数据。

三、异步编程

异步编程是一种高效的并发编程方式,尤其适用于I/O密集型任务。Python中的asyncio模块提供了异步编程的支持,可以使用协程实现非阻塞的并发执行。

1. 协程

协程是一种可以在执行过程中暂停和恢复的函数。协程使用async def关键字定义,使用await关键字调用。

1.1 定义和调用协程

以下示例展示了如何定义和调用协程:

import asyncio

async def print_numbers():
    for i in range(1, 6):
        print(i)
        await asyncio.sleep(1)

# 获取事件循环
loop = asyncio.get_event_loop()

# 运行协程
loop.run_until_complete(print_numbers())
loop.close()
print("Coroutine execution completed.")

在上面的例子中,我们定义了一个协程print_numbers,并在事件循环中运行它。await asyncio.sleep(1)用于模拟异步操作。

2. 异步任务

在异步编程中,我们可以使用asyncio.create_task创建异步任务,并使用await等待任务完成。

以下示例展示了如何创建和管理异步任务:

import asyncio

async def print_numbers():
    for i in range(1, 6):
        print(i)
        await asyncio.sleep(1)

async def main():
    # 创建异步任务
    task1 = asyncio.create_task(print_numbers())
    task2 = asyncio.create_task(print_numbers())

    # 等待所有任务完成
    await asyncio.gather(task1, task2)

# 获取事件循环并运行主协程
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
print("All tasks completed.")

在上面的例子中,我们创建了两个异步任务,并使用asyncio.gather等待它们全部完成。

四、并发编程的实际应用示例

并发编程在实际应用中有广泛的应用,以下是两个实际应用示例,演示如何使用Python进行并发编程。

1. 多线程Web爬虫

以下示例演示如何使用多线程实现一个简单的Web爬虫:

import threading
import requests
from bs4 import BeautifulSoup

urls = [
    'https://www.example.com/page1',
    'https://www.example.com/page2',
    'https://www.example.com/page3'
]

def fetch_url(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    title = soup.title.string
    print(f"Title of {url}: {title}")

# 创建和启动线程
threads = []
for url in urls:
    thread = threading.Thread(target=fetch_url, args=(url,))
    threads.append(thread)
    thread.start()

# 等待所有线程结束
for thread in threads:
    thread.join()

print("All URLs fetched.")

在上面的例子中,我们使用多线程来并发获取多个网页的标题,从而提高爬取效率。

2. 多进程图像处理

以下示例演示如何使用多进程实现并行图像处理:

import multiprocessing
from PIL import Image, ImageFilter

image_paths = [
    'image1.jpg',
    'image2.jpg',
    'image3.jpg'
]

def process_image(image_path):
    image = Image.open(image_path)
    image = image.filter(ImageFilter.GaussianBlur(5))
    output_path = f"processed_{

image_path}"
    image.save(output_path)
    print(f"Processed {image_path} and saved as {output_path}")

# 创建和启动进程
processes = []
for image_path in image_paths:
    process = multiprocessing.Process(target=process_image, args=(image_path,))
    processes.append(process)
    process.start()

# 等待所有进程结束
for process in processes:
    process.join()

print("All images processed.")

在上面的例子中,我们使用多进程来并行处理多个图像,从而提高图像处理的效率。

五、并发编程的注意事项

并发编程可以显著提高程序的性能,但同时也带来了一些挑战和问题。以下是一些并发编程的注意事项:

1. 线程安全

在多线程编程中,多个线程可能会同时访问共享资源,从而导致数据不一致的问题。为了避免这种情况,我们需要使用线程同步机制,如锁(Lock)、信号量(Semaphore)等。

2. 死锁

死锁是指两个或多个线程互相等待对方释放资源,从而导致程序无法继续执行的情况。为了避免死锁,我们需要小心设计线程同步机制,避免循环等待的情况。

3. 资源消耗

线程和进程的创建和管理会消耗系统资源。在实际应用中,我们需要合理控制线程和进程的数量,避免资源浪费。

4. 异常处理

在并发编程中,异常处理尤为重要。我们需要捕获和处理并发任务中的异常,确保程序的稳定性和可靠性。

结论

并发编程是现代编程中的一个重要技术,可以显著提高程序的性能和响应速度。在Python中,有多种方式可以实现并发编程,包括线程、多进程和异步编程。通过理解和掌握这些技术,我们可以编写出更加高效和可靠的程序。在本文中,我们详细讨论了并发编程的基本概念、Python中的线程与进程、多线程编程、多进程编程、异步编程以及并发编程的实际应用示例。希望这篇文章能帮助你更好地理解和应用Python中的并发编程技术,从而在实际项目中获得更多的性能提升和优化效果。

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

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

相关文章

【Python数据预处理系列】掌握数据清洗技巧:如何高效使用drop()函数去除不需要的列

目录 一、准备数据 二、使用drop函数去除掉指定列 在数据分析和预处理的过程中,经常会遇到需要从数据集中移除某些列的情况。本文将引导您了解如何使用drop函数高效地去除不需要的列,帮助您提升数据处理技能,确保您的数据集只包含对分析有价…

数据采集边缘网关解决企业数据采集痛点-天拓四方

随着信息技术的快速发展,企业对于数据采集和处理的需求日益增长。然而,传统的数据采集方式往往面临着数据量大、传输延迟、安全性不足等问题,给企业的运营和管理带来了诸多挑战。在这样的背景下,数据采集边缘网关应运而生&#xf…

注意,CCNA版本即将更新至V1.1

下午好同学们,思科发布了CCNA 1.1版本的更新,这次更新不仅涉及到考试内容的调整,也同样从侧面反映了网络技术的发展趋势。 震惊!思科为了与时俱进,NA居然做出这种事! 今天就从更新内容概览、考试大纲的变…

dynamic多数据源的简单使用

背景 这几天搞了个saas项目,里面用到了多数据和execl模板导出功能, 其实我是经常用到的,但没在博客中写过,最近有点时间,正好稍微写一下。 方便大家使用 这次我先写多数据,execl模板导出下次有空在写。 使…

手机怎么压缩视频?归纳了三种快速压缩方案

手机怎么压缩视频?在数字时代,手机已经成为我们记录生活的重要工具,而视频作为其中的一种主要形式,更是占据了极大的存储空间。然而,随着手机拍摄的视频越来越多,如何高效压缩视频以节省存储空间&#xff0…

数组array 和 array的区别

问题 对于数组 array和&array有什么区别呢? 先说答案 array: 指向数组第一个数地址的指针 &array: 指向整个数组地址的指针 所以直接打印的话, 地址是一样的. 但是如果1的话, 那么array是增加sizeof(int)大小, &array是增加sizeof(int) * array.size() 测试 #i…

金融科技赋能跨境支付:便捷与安全并驾齐驱

一、引言 在全球经济一体化的背景下,跨境支付作为国际贸易和金融活动的重要组成部分,正迎来金融科技浪潮的洗礼。金融科技以其独特的创新性和颠覆性,正在重塑跨境支付市场的格局,使其更加便捷、高效且安全。本文旨在探讨金融科技如何助力跨境支付,实现便捷与安全并存,并…

QT系列教程(8) QT 布局学习

简介 Qt 中的布局有三种方式,水平布局,垂直布局,栅格布局。 通过ui设置布局 我们先创建一个窗口应用程序,程序名叫layout,基类选择QMainWindow。但我们不使用这个mainwindow,我们创建一个Qt应用程序类Log…

五大PS插件推荐,让你的设计效率翻倍!

前言 PS插件可以在繁忙的设计工作中,帮助设计师们快速高效地完成任务,是每个设计师都渴望解决的问题。这些插件不仅能够提升设计效率,还能让设计师的创意得到更好的展现。接下来,就为大家推荐五款必备的PS插件,让你的…

0基础学习区块链技术——去中心化

大纲 去验证的中心化验证者如何验证验证者为什么要去传播 去确认的中心化去存储的中心化 “去中心化”是区块链技术的核心。那么我们该如何理解这个概念呢? 我们可以假想在一次现实转账中,有哪些“中心化”的行为: 判断余额是否足够。即判断…

【成品设计】基于433模块的人体检测响铃控制系统

《基于433模块的人体检测响铃控制系统》 整体功能: A端的器件: 单片机(STM32C8T6) 2.人体感应模块: 引脚连接: 1.VCC:正极 3.3-5V供电 2.GND:负极 接GND 3.DO(数字量输…

19 - 查询结果的质量和占比(高频 SQL 50 题基础版)

19 - 查询结果的质量和占比 -- round(avg(rating<3)*100,2)round(avg(if(rating<3,1,0))*100,2) select query_name,round(avg(rating/position),2) quality,round(avg(if(rating<3,1,0))*100,2) poor_query_percentage fromQueries group byquery_name;

ScrollViewer—WPF滚动条控件

ScrollViewer—WPF滚动条控件 参考地址&#xff1a;ScrollViewer 概述 - WPF .NET Framework | Microsoft Learn 1.ScrollViewer定义与功能 ScrollViewer是WPF应用程序的一个容器控件&#xff0c;用于在可以滚动的区域中显示其他可见元素。ScrollViewer封装&#xff1b; 水平…

网络高频攻击手段与基本防护措施总结

主要攻击手段 一、云平台攻击 云平台攻击是指针对云服务器的恶意行为&#xff0c;旨在获取非法访问权限、窃取敏感数据或者破坏服务器的正常运行。云平台攻击的形式多样&#xff0c;以下是对云平台攻击的一些主要类型和特点的详细分析&#xff1a; 攻击类型&#xff1a; 凭据…

数字人AI唇音同步解决方案,轻量高效,灵活部署

在数字化浪潮的推动下&#xff0c;企业对于高效、逼真的数字人形象需求日益增强。为满足这一市场需求&#xff0c;美摄科技凭借其深厚的AI技术积累&#xff0c;推出了一款革命性的数字人AI唇音同步解决方案&#xff0c;为企业带来前所未有的沟通体验。 一、精准捕捉&#xff0…

C语言(联合和枚举)

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习笔记&#xff0c;在这里撰写成…

00-macOS和Linux安装和管理多个Python版本

在 Mac 上安装多个 Python 版本可通过几种不同方法实现。 1 Homebrew 1.1 安装 Homebrew 若安装过&#xff0c;跳过该步。 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 1.2 安装 Python 如安装 Python …

Java多线程-初阶1

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多数据结构知识 1. 认识线程&#xff08;Thread&#xff09; 1.线程是什么 ⼀个线程就是⼀个 "执⾏流". 每个线程之间都可以按照顺序执⾏⾃⼰的代…

动态规划7:LCR 166. 珠宝的最高价值

动态规划解题步骤&#xff1a; 1.确定状态表示&#xff1a;dp[i]是什么 2.确定状态转移方程&#xff1a;dp[i]等于什么 3.初始化&#xff1a;确保状态转移方程不越界 4.确定填表顺序&#xff1a;根据状态转移方程即可确定填表顺序 5.确定返回值 题目链接&#xff1a;LCR …

sap 应用日志-Application Log

文章目录 sap 应用日志-Application Log概念事务代码函数创建程序显示配置文件运行结果弹出式全屏式 程序剖析清空日志创建日志模拟数据添加日志消息显示日志BAL_DSP_LOG_DISPLAY-显示内存消息 全部程序 sap 应用日志-Application Log 概念 SAP 应用日志&#xff08;Applicat…