Python的多线程和多进程

一、简介

并发是今天计算机编程中的一项重要能力,尤其是在面对需要大量计算或I/O操作的任务时。Python 提供了多种并发的处理方式,本篇文章将深入探讨其中的两种:多线程与多进程,解析其使用场景、优点、缺点,并结合代码例子深入解读。

二、多线程

Python中的线程是利用threading模块实现的。线程是在同一个进程中运行的不同任务。

2.1 线程的基本使用

在Python中创建和启动线程很简单。下面是一个简单的例子:

import threading
import time def print_numbers():
for i in range(10):
time.sleep(1)
print(i) def print_letters():
for letter in 'abcdefghij':
time.sleep(1.5)
print(letter) thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_letters) thread1.start()
thread2.start()

在这个例子中,print_numbersprint_letters函数都在各自的线程中执行,彼此互不干扰。

2.2 线程同步

由于线程共享内存,因此线程间的数据是可以互相访问的。但是,当多个线程同时修改数据时就会出现问题。为了解决这个问题,我们需要使用线程同步工具,如锁(Lock)和条件(Condition)等。

import threading

class BankAccount:
def __init__(self):
self.balance = 100 # 共享数据
self.lock = threading.Lock() def deposit(self, amount):
with self.lock: # 使用锁进行线程同步
balance = self.balance
balance += amount
self.balance = balance def withdraw(self, amount):
with self.lock: # 使用锁进行线程同步
balance = self.balance
balance -= amount
self.balance = balance account = BankAccount()

特别说明:Python的线程虽然受到全局解释器锁(GIL)的限制,但是对于IO密集型任务(如网络IO或者磁盘IO),使用多线程可以显著提高程序的执行效率。

三、多进程

Python中的进程是通过multiprocessing模块实现的。进程是操作系统中的一个执行实体,每个进程都有自己的内存空间,彼此互不影响。

3.1 进程的基本使用

在Python中创建和启动进程也是非常简单的:

from multiprocessing import Process
import os def greet(name):
print(f'Hello {name}, I am process {os.getpid()}') if __name__ == '__main__':
process = Process(target=greet, args=('Bob',))
process.start()
process.join()

3.2 进程间的通信

由于进程不共享内存,因此进程间通信(IPC)需要使用特定的机制,如管道(Pipe)、队列(Queue)等。

from multiprocessing import Process, Queue

def worker(q):
q.put('Hello from process') if __name__ == '__main__':
q = Queue()
process = Process(target=worker, args=(q,))
process.start()
process.join() print(q.get()) # Prints: Hello from process

特别说明:Python的多进程对于计算密集型任务是一个很好的选择,因为每个进程都有自己的Python解释器和内存空间,可以并行计算。

One More Thing

让我们再深入地看一下concurrent.futures模块,这是一个在Python中同时处理多线程和多进程的更高级的工具。concurrent.futures

块提供了一个高级的接口,将异步执行的任务放入到线程或者进程的池中,然后通过future对象来获取执行结果。这个模块使得处理线程和进程变得更简单。

下面是一个例子:

from concurrent.futures import ThreadPoolExecutor, as_completed

def worker(x):
return x * x with ThreadPoolExecutor(max_workers=4) as executor:
futures = {executor.submit(worker, x) for x in range(10)}
for future in as_completed(futures):
print(future.result())

这个代码创建了一个线程池,并且向线程池提交了10个任务。然后,通过future对象获取每个任务的结果。这里的as_completed函数提供了一种处理完成的future的方式。

通过这种方式,你可以轻松地切换线程和进程,只需要将ThreadPoolExecutor更改为ProcessPoolExecutor

无论你是处理IO密集型任务还是计算密集型任务,Python的多线程和多进程都提供了很好的解决方案。理解它们的运行机制和适用场景,可以帮助你更好地设计和优化你的程序。

如有帮助,请多关注

个人微信公众号:【Python全视角】

TeahLead_KrisChang,10+年的互联网和人工智能从业经验,10年+技术和业务团队管理经验,同济软件工程本科,复旦工程管理硕士,阿里云认证云服务资深架构师,上亿营收AI产品业务负责人。

一文掌握Python多线程与多进程的更多相关文章

  1. Python多线程和多进程谁更快?

    python多进程和多线程谁更快 python3.6 threading和multiprocessing 四核+三星250G-850-SSD 自从用多进程和多线程进行编程,一致没搞懂到底谁更快.网上很 ...

  2. Python 多线程、多进程 (三)之 线程进程对比、多进程

    Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.多线程与多进 ...

  3. 基于Windows平台的Python多线程及多进程学习小结

    python多线程及多进程对于不同平台有不同的工具(platform-specific tools),如os.fork仅在Unix上可用,而windows不可用,该文仅针对windows平台可用的工具 ...

  4. python多线程与多进程--存活主机ping扫描以及爬取股票价格

    python多线程与多进程 多线程: 案例:扫描给定网络中存活的主机(通过ping来测试,有响应则说明主机存活) 普通版本: #扫描给定网络中存活的主机(通过ping来测试,有响应则说明主机存活)im ...

  5. Python 多线程、多进程 (一)之 源码执行流程、GIL

    Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.python ...

  6. Python 多线程、多进程 (二)之 多线程、同步、通信

    Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.python ...

  7. python多线程与多进程及其区别

    个人一直觉得对学习任何知识而言,概念是相当重要的.掌握了概念和原理,细节可以留给实践去推敲.掌握的关键在于理解,通过具体的实例和实际操作来感性的体会概念和原理可以起到很好的效果.本文通过一些具体的例子 ...

  8. python 多线程、多进程

    一.首先说下多线程.多进程用途及异同点,另外还涉及到队列的,memcache.redis的操作等: 1.在python中,如果一个程序是IO密集的操作,使用多线程:运算密集的操作使用多进程. 但是,其 ...

  9. python多线程,多进程

    线程是公用内存,进程内存相互独立 python多线程只能是一个cpu,java可以将多个线程平均分配到其他cpu上 以核为单位,所以GIL(全局锁,保证线程安全,数据被安全读取)最小只能控制一个核,很 ...

  10. 搞定python多线程和多进程

    1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发 ...

随机推荐

  1. cephadm 安装部署 ceph 集群

    介绍 手册: https://access.redhat.com/documentation/zh-cn/red_hat_ceph_storage/5/html/architecture_guide/ ...

  2. docker方式实现redis数据持久化离线安装

    保存镜像 root@hello:~# docker pull redis:latest latest: Pulling from library/redis a2abf6c4d29d: Already ...

  3. python之pdf转换操作 PyMuPDF库学习

    1. 资料链接github地址: pymupdf/PyMuPDF: Python bindings for MuPDF's rendering library官方手册: PyMuPDF Documen ...

  4. 解决CKEditor中img标签自动添加style样式的问题-禁止自动设置width和height 帝国cms编辑器图片自动加宽高

    在使用CKEditor的过程中发现,每次上传或添加图片的时候,总会自动给img标签添加width和height的style内联样式.由于网站本身对图片有进行自适应处理(添加了自适应的CSS),所以im ...

  5. Qt开发技术:Q3D图表开发笔记(三):Q3DSurface三维曲面图介绍、Demo以及代码详解

    前言   qt提供了q3d进行三维开发,虽然这个框架没有得到大量运用也不是那么成功,性能上也有很大的欠缺,但是普通的点到为止的应用展示还是可以的.  其中就包括华丽绚烂的三维图表,数据量不大的时候是可 ...

  6. cesium源码编译调试及调用全过程

    完整记录一次cesium源码从下载.打包.调用.调试的全过程. 本文使用软件或API版本: VSCode Node:12.18.3 cesium版本:1.94 总体步骤: 下载源码 执行npm ins ...

  7. 一文讲透产品经理如何用好ChatGPT

    作者:京东零售 何雨航 "4.0版本的ChatGPT可以有效提升产品经理工作效率,但并无法替代产品经理的角色." 一.引言 3月15日,OpenAI发布了最新的基于GPT-4的Ch ...

  8. 明解STM32—GPIO应用设计篇之API函数及配置使用技巧

    一.前言 本篇开始对STM32的GPIO在实际开发设计中的使用配置和技巧进行探讨,可以先去回顾下之前介绍的GPIO的相关理论基础知识包括基本结构,工作模式和寄存器原理. 了解过STM32的GPIO相关 ...

  9. vue中父组件给子组件传值的方法

    顺序............................................. -------------列表组件,注册组件.调用使用组件----------------- 1,子组件 ...

  10. ElementPlus 组件全局配置

    友链:语雀,在线文档协同平台 官方提供的全局配置:Config Provider 本文只做简单的模板参考,具体的配置请根据自己的业务灵活设置,如果你使用的是其它的ui框架,原理应该都差不多 入口文件的 ...