Python并发编程的艺术:掌握线程、进程与协程的同步技巧

本文涉及的产品
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: 并发编程在Python中涵盖线程、进程和协程,用于优化IO操作和响应速度。`threading`模块支持线程,`multiprocessing`处理进程,而`asyncio`则用于协程。线程通过Lock和Condition Objects同步,进程使用Queue和Pipe通信。协程利用异步事件循环避免上下文切换。了解并发模型及同步技术是提升Python应用性能的关键。

并发编程是现代软件开发中的重要组成部分,尤其在处理大量IO操作、提升应用响应速度和资源利用率方面发挥着关键作用。Python,作为一门广泛应用于科学计算、Web开发、数据分析等多个领域的高级编程语言,提供了多种并发编程模型,包括线程、进程以及更高级的协程。本文将深入探讨这三种并发模型,特别是它们的同步技巧,通过理论讲解与实战代码案例相结合,帮助读者掌握Python并发编程的艺术。

1. 并发编程基础

并发是指程序在一段时间内同时处理多个任务的能力。这并不意味着所有的任务都在同一时刻执行(这在单核处理器上是不可能的),而是指通过时间切片、多处理器或异步IO等方式,让多个任务看似同时进行。并发提高了资源利用率,使得程序能够更高效地处理任务。

1.1 并发与并行的区别

  • 并发:指任务在宏观上同时进行,微观上可能交替执行。
  • 并行:指任务在微观上同时执行,通常需要多核处理器支持。

2. Python中的线程

线程是操作系统能够进行调度的最小执行单位。在Python中,可以通过threading模块创建和管理线程。

2.1 创建线程

import threading
import time

def thread_function(name):
    print(f"Thread {name}: starting")
    time.sleep(2)
    print(f"Thread {name}: finishing")

if __name__ == "__main__":
    threads = list()
    for index in range(3):
        thread = threading.Thread(target=thread_function, args=(index,))
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()
    print("Main thread finished")

2.2 同步:Locks与Condition Objects

Locks

为了避免多个线程同时修改共享资源引发的数据不一致性,可以使用Lock

import threading

counter = 0
lock = threading.Lock()

def increment():
    global counter
    with lock:
        local_counter = counter
        local_counter += 1
        time.sleep(0.1)  # 模拟IO延迟
        counter = local_counter

threads = [threading.Thread(target=increment) for _ in range(100)]
for thread in threads:
    thread.start()
for thread in threads:
    thread.join()

print(f"Counter: {counter}")

Condition Objects

Condition对象允许一个或多个线程等待直到某个条件满足。

import threading

condition = threading.Condition()
workers = 5

def worker(num):
    with condition:
        while True:
            if workers > 0:
                print(f"Worker {num} starts working")
                workers -= 1
                condition.notify_all()
                break
            else:
                print(f"No work for worker {num}, waiting...")
                condition.wait()

threads = [threading.Thread(target=worker, args=(i,)) for i in range(10)]
for thread in threads:
    thread.start()
for thread in threads:
    thread.join()

3. Python中的进程

进程是资源分配的最小单位,拥有独立的内存空间。Python的multiprocessing模块提供了创建和管理进程的功能。

3.1 进程间通信

使用Queue

from multiprocessing import Process, Queue

def worker(q):
    item = q.get()
    print(f'Processing {item}')

if __name__ == '__main__':
    q = Queue()
    p = Process(target=worker, args=(q,))
    p.start()
    q.put(1)
    p.join()

使用Pipe

from multiprocessing import Process, Pipe

def sender(conn, msgs):
    for msg in msgs:
        conn.send(msg)
    conn.close()

def receiver(conn):
    while True:
        msg = conn.recv()
        if msg == 'END':
            break
        print(f"Received: {msg}")
    conn.close()

if __name__ == '__main__':
    parent_conn, child_conn = Pipe()
    p = Process(target=sender, args=(child_conn, ['Hello', 'World', 'END']))
    p.start()
    receiver(parent_conn)
    p.join()

4. Python中的协程

协程是一种轻量级的线程,通过在单线程内实现任务切换,避免了线程上下文切换的开销。Python通过asyncio模块支持协程。

4.1 异步编程基础

import asyncio

async def my_coroutine():
    print('Coroutine started.')
    await asyncio.sleep(1)
    print('Coroutine finished.')

async def main():
    task = asyncio.create_task(my_coroutine())
    await task

asyncio.run(main())

4.2 使用asyncio的Event Loop与Tasks

import asyncio

async def my_task(number):
    print(f'Task {number} started')
    await asyncio.sleep(1)
    print(f'Task {number} finished')

async def main():
    tasks = []
    for i in range(5):
        tasks.append(asyncio.create_task(my_task(i)))
    await asyncio.gather(*tasks)

asyncio.run(main())

4.3 异步共享状态与Locks

尽管协程在单线程内执行,但当涉及到共享状态时,依然需要同步机制。

import asyncio

async def increment(counter, lock):
    async with lock:
        global num
        num = counter.value + 1
        counter.value = num
        await asyncio.sleep(0.1)

async def main():
    counter = asyncio.Value('i', 0)
    lock = asyncio.Lock()
    tasks = [increment(counter, lock) for _ in range(100)]
    await asyncio.gather(*tasks)
    print(f"Final count: {counter.value}")

asyncio.run(main())

5. 总结

Python的并发编程模型为开发者提供了从线程、进程到协程的多样化选择,每种模型都有其适用场景。理解这些模型的核心概念、掌握它们之间的区别与同步技巧,是提升应用性能的关键。通过上述代码案例的学习,希望读者能够深入理解Python并发编程的艺术,灵活运用线程、进程与协程,有效地解决并发场景下的各种挑战。

目录
相关文章
|
11月前
|
人工智能 安全 调度
Python并发编程之线程同步详解
并发编程在Python中至关重要,线程同步确保多线程程序正确运行。本文详解线程同步机制,包括互斥锁、信号量、事件、条件变量和队列,探讨全局解释器锁(GIL)的影响及解决线程同步问题的最佳实践,如避免全局变量、使用线程安全数据结构、精细化锁的使用等。通过示例代码帮助开发者理解并提升多线程程序的性能与可靠性。
324 0
|
11月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
439 0
|
11月前
|
数据采集 NoSQL 调度
当生成器遇上异步IO:Python并发编程的十大实战兵法
本文通过十大实战场景,详解Python中生成器与异步IO的高效结合。从协程演进、背压控制到分布式锁、性能剖析,全面展示如何利用asyncio与生成器构建高并发应用,助你掌握非阻塞编程核心技巧,提升I/O密集型程序性能。
410 0
|
11月前
|
监控 编译器 Python
如何利用Python杀进程并保持驻留后台检测
本教程介绍如何使用Python编写进程监控与杀进程脚本,结合psutil库实现后台驻留、定时检测并强制终止指定进程。内容涵盖基础杀进程、多进程处理、自动退出机制、管理员权限启动及图形界面设计,并提供将脚本打包为exe的方法,适用于需持续清理顽固进程的场景。
|
12月前
|
数据采集 搜索推荐 调度
当生成器遇上异步IO:Python并发编程的十大实战兵法
生成器与异步IO是Python并发编程中的两大利器,二者结合可解决诸多复杂问题。本文通过十个真实场景展示其强大功能:从优雅追踪日志文件、API调用流量整形,到实时数据流反压控制、大文件分片处理等,每个场景都体现了生成器按需生成数据与异步IO高效利用I/O的优势。两者配合不仅内存可控、响应及时,还能实现资源隔离与任务独立调度,为高并发系统提供优雅解决方案。这种组合如同乐高积木,虽单个模块简单,但组合后却能构建出复杂高效的系统。
263 0
Python 高级编程与实战:深入理解面向对象与并发编程
本文深入探讨Python的高级特性,涵盖面向对象编程(继承、多态、特殊方法、类与实例属性)、异常处理(try-except、finally)和并发编程(多线程、多进程、异步编程)。通过实战项目如聊天服务器和异步文件下载器,帮助读者掌握这些技术,编写更复杂高效的Python程序。
|
机器学习/深度学习 分布式计算 API
Python 高级编程与实战:深入理解并发编程与分布式系统
在前几篇文章中,我们探讨了 Python 的基础语法、面向对象编程、函数式编程、元编程、性能优化、调试技巧、数据科学、机器学习、Web 开发、API 设计、网络编程和异步IO。本文将深入探讨 Python 在并发编程和分布式系统中的应用,并通过实战项目帮助你掌握这些技术。
|
数据采集 消息中间件 Java
python并发编程:什么是并发编程?python对并发编程有哪些支持?
并发编程能够显著提升程序的效率和响应速度。例如,网络爬虫通过并发下载将耗时从1小时缩短至20分钟;APP页面加载时间从3秒优化到200毫秒。Python支持多线程、多进程、异步I/O和协程等并发编程方式,适用于不同场景。线程通信方式包括共享变量、消息传递和同步机制,如Lock、Queue等。Python的并发编程特性使其在处理大规模数据和高并发访问时表现出色,成为许多领域的首选语言。
287 3
|
数据采集 Java 数据处理
Python实用技巧:轻松驾驭多线程与多进程,加速任务执行
在Python编程中,多线程和多进程是提升程序效率的关键工具。多线程适用于I/O密集型任务,如文件读写、网络请求;多进程则适合CPU密集型任务,如科学计算、图像处理。本文详细介绍这两种并发编程方式的基本用法及应用场景,并通过实例代码展示如何使用threading、multiprocessing模块及线程池、进程池来优化程序性能。结合实际案例,帮助读者掌握并发编程技巧,提高程序执行速度和资源利用率。
764 0
|
监控 JavaScript 前端开发
python中的线程和进程(一文带你了解)
欢迎来到瑞雨溪的博客,这里是一位热爱JavaScript和Vue的大一学生分享技术心得的地方。如果你从我的文章中有所收获,欢迎关注我,我将持续更新更多优质内容,你的支持是我前进的动力!🎉🎉🎉
274 0

推荐镜像

更多