深入理解Python中的多进程和多线程

news2024/12/21 22:23:14

  前言

此篇文章将深入的讲解Python中的多进程和多线程

b1691e6f246947eeb06ee06469621bc2.gif

📝个人主页→数据挖掘博主ZTLJQ的主页

个人推荐python学习系列:

☄️爬虫JS逆向系列专栏 - 爬虫逆向教学

☄️python系列专栏 - 从零开始学python

第一部分:多进程

多进程是指在操作系统中同时运行多个独立的程序或子进程。Python中的multiprocessing模块提供了创建和管理多进程的功能。

案例1:使用多进程进行计算密集型任务

import multiprocessing

def square(n):
    return n*n

if __name__ == '__main__':
    numbers = [1, 2, 3, 4, 5]
    pool = multiprocessing.Pool()

    results = pool.map(square, numbers)
    pool.close()
    pool.join()

    print(results)

解释:

  • 定义了一个square函数,用于计算给定数值的平方。
  • 在主程序中,创建了一个数字列表numbers。
  • 使用multiprocessing.Pool()创建一个进程池pool。
  • 调用pool.map()方法,将square函数应用到numbers列表中的每个数值上进行计算。
  • 最后,输出计算结果。

案例2:使用多进程进行IO密集型任务

import multiprocessing
import requests

def download(url):
    response = requests.get(url)
    content = response.content
    with open('file_' + url.split('/')[-1], 'wb') as file:
        file.write(content)

if __name__ == '__main__':
    urls = ['http://example.com', 'http://example.org', 'http://example.net']
    pool = multiprocessing.Pool()

    pool.map(download, urls)
    pool.close()
    pool.join()

解释:

  • 导入requests模块,用于发送HTTP请求。
  • 定义了一个download函数,用于下载给定URL的内容,并保存为文件。
  • 在主程序中,创建了一个URL列表urls。
  • 使用multiprocessing.Pool()创建一个进程池pool。
  • 调用pool.map()方法,将download函数应用到urls列表中的每个URL上进行下载。
  • 最后,所有文件下载完成后,进程池关闭。

案例3:多进程实现并行任务

import multiprocessing
import time

def task(name):
    print(f'Starting task {name}')
    time.sleep(2)
    print(f'Finished task {name}')

if __name__ == '__main__':
    processes = []

    for i in range(1, 6):
        p = multiprocessing.Process(target=task, args=(f'Task {i}',))
        p.start()
        processes.append(p)

    for p in processes:
        p.join()

    print('All tasks completed.')

解释:

  • 定义了一个task函数,模拟一个耗时的任务,并在开始和结束时打印相关信息。
  • 在主程序中,创建了一个进程列表processes。
  • 使用for循环创建并启动5个子进程,每个子进程执行task函数,并传入不同的任务名称作为参数。
  • 调用join()方法等待所有子进程的执行完成。
  • 最后,打印所有任务完成的提示信息。

第二部分:多线程

多线程是指在一个程序中同时运行多个独立的线程。Python中的threading模块提供了创建和管理多线程的功能。

案例1:使用多线程进行并发请求

import threading
import requests

def fetch(url):
    response = requests.get(url)
    content = response.content
    print(f'Response from {url}: {content}')

if __name__ == '__main__':
    urls = ['http://example.com', 'http://example.org', 'http://example.net']
    threads = []

    for url in urls:
        t = threading.Thread(target=fetch, args=(url,))
        threads.append(t)
        t.start()

    for t in threads:
        t.join()

解释:

  • 导入requests模块,用于发送HTTP请求。
  • 定义了一个fetch函数,用于请求给定URL的内容,并输出响应内容。
  • 在主程序中,创建了一个URL列表urls。
  • 创建一个线程列表threads来存储所有的子线程。
  • 使用for循环创建子线程,每个子线程都调用fetch函数,并传入不同的URL参数。
  • 调用start()方法启动子线程,使它们开始执行。
  • 最后,使用join()方法等待所有子线程的执行完成,并输出响应结果。

案例2:多线程实现资源共享

import threading

count = 0
lock = threading.Lock()

def increment():
    global count
    with lock:
        count += 1
        print(f'Count: {count}')

if __name__ == '__main__':
    threads = []

    for i in range(10):
        t = threading.Thread(target=increment)
        t.start()
        threads.append(t)

    for t in threads:
        t.join()

    print('Final count:', count)

解释:

  • 定义了一个全局变量count,用于记录递增的值。
  • 创建了一个线程锁lock,用于保护共享资源count的访问。
  • 定义了一个increment函数,使用线程锁来确保每次递增操作的原子性。
  • 在主程序中,创建了一个线程列表threads。
  • 使用for循环创建并启动10个子线程,每个子线程执行increment函数。
  • 调用join()方法等待所有子线程的执行完成。
  • 最后,打印最终的count值。

案例3:多线程队列示例

import threading
import queue

def producer(q, name):
    for i in range(5):
        message = f'Message {i} from {name}'
        q.put(message)
        print(f'Produced: {message}')

def consumer(q, name):
    while not q.empty():
        message = q.get()
        print(f'Consumed by {name}: {message}')

if __name__ == '__main__':
    q = queue.Queue()

    p1 = threading.Thread(target=producer, args=(q, 'Producer 1'))
    p2 = threading.Thread(target=producer, args=(q, 'Producer 2'))
    c1 = threading.Thread(target=consumer, args=(q, 'Consumer 1'))
    c2 = threading.Thread(target=consumer, args=(q, 'Consumer 2'))

    p1.start()
    p2.start()
    c1.start()
    c2.start()

    p1.join()
    p2.join()
    c1.join()
    c2.join()

    print('All messages consumed.')

多线程队列示例是一个典型的生产者-消费者模型,其中有两个生产者线程(Producer 1和Producer 2)和两个消费者线程(Consumer 1和Consumer 2)。它们共享一个线程安全的队列(Queue)来进行信息交换。

在生产者线程中,每个生产者会循环生成5条消息,并将它们放入队列中。每条消息都包含了消息的编号和产生消息的生产者的名称。生产者线程在生产完所有消息之后结束。

在消费者线程中,每个消费者会不断地从队列中取出消息,并打印出消费的消息以及消费者的名称。消费者线程会一直运行,直到队列为空时才结束。

主线程创建并启动了所有生产者和消费者线程,并等待它们全部执行完毕。最后,主线程打印出"All messages consumed."表示所有消息都被消费完毕。

通过使用线程安全的队列,多线程之间可以安全地进行信息的传递和共享,避免了数据竞争和死锁等多线程编程常见问题。

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

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

相关文章

STL stack,queue,deque以及适配器

目录 stackstack的使用stack模拟实现 queuequeue的使用queue模拟实现 适配器deque stack stack的使用 下面是stack库中的接口函数,有了前面的基础,我们可以根据函数名得知函数的作用 函数说明stack()构造空栈empty()判断栈是否为空size()返回栈中元素…

keil5 快捷下载STM32系列芯片器件包的方法

以STM32H7系列的器件包为例,官网的下载网址为 https://sadevicepacksprodus.blob.core.windows.net/pack/Keil.STM32H7xx_DFP.3.1.1.pack 其中STM32H7xx为芯片系列编号,3.1.1为器件包的版本 如需下载其他系列和版本的器件包,只需把网址中的编号和版本换成对应的即可(前提是输入…

Websocket、SessionCookie、前端基础知识

目录 1.Websocket Websocket与HTTP的介绍 不同使用场景 Websocket链接过程 2.Session&Cookie Cookie的工作原理 Session的工作原理 区别 3.前端基础知识 1.Websocket Websocket与HTTP的介绍 HTTP: 1.HTTP是单向的,客户端发送请求&#xff0…

OWS.infg应用程序隐私政策

本软件尊重并保护所有使用服务用户的个人隐私权。为了给您提供更准确、更有个性化的服务,本软件目前不会使用和披露您的个人信息。但本软件会不时更新本隐私权政策。您在同意本软件服务使用协议之时,即视为您已经同意本隐私权政策全部内容。本隐私权政策…

OJ练习第154题——到家的最少跳跃次数

到家的最少跳跃次数 力扣链接:1654. 到家的最少跳跃次数 题目描述 有一只跳蚤的家在数轴上的位置 x 处。请你帮助它从位置 0 出发,到达它的家。 跳蚤跳跃的规则如下: 它可以 往前 跳恰好 a 个位置(即往右跳)。 它…

【数据结构】——查找、散列表的相关习题

目录 一、选择填空判断题题型一(顺序、二分查找的概念)题型二(分块查找的概念)题型三(关键字比较次数) 二、应用题题型一(二分查找判定树) 一、选择填空判断题 题型一(顺…

1、英飞凌-AURIX-TC297简介

目录 TC297简介TC297特点:系统优势最具创新性的安全应用场景 printf("欢迎关注公众号:Kevin的学习站/车载嵌入式探索者,博主建立了一个车规级开发交流群, 感兴趣的朋友可以关注公众号,加个人WX:_kevin…

医疗小程序:让服务更高效,用户体验更优化

随着移动互联网的快速发展,小程序已经成为了一个热门的开发方向。医疗健康类小程序也不例外,拥有广泛的市场需求和前景。本文将为你提供一份完整的医疗健康类小程序开发攻略,帮助你快速开发上线一个专业成熟的小程序商城。 一、选择合适的小程…

C++(17):异常处理

异常处理机制允许程序中独立开发的部分能够在运行时就出现的问题进行通信并做出相应的处理。 异常使得能够将问题的检测与解决过程分离开来:程序的一部分负责检测问题的出现,然后解决该问题的任务传递给程序的另一部分。检测环节无须知道问题处理模块的…

Android 音频框架 基于android 12

文章目录 前言音频服务audioserver音频数据链路hal 提供什么样的作用 前言 Android 的音频是一个相当复杂的部分。从应用到框架、hal、kernel、最后到硬件,每个部分的知识点都相当的多。而android 这部分代码在版本之间改动很大、其中充斥着各种workaround的处理&a…

AI能完全取代PS吗?两者僵持背后的设计思路!

PS 是功能强大的位图图片处理软件。它的核心功能是图片处理,最大特点是放大图片时会出现马赛克模糊。PS 存在下载安装复杂,功能繁杂,新手不易上手等缺点。越来越多设计师更青睐轻量级的协作设计软件,例如新一代国产软件即时设计。…

openCV实战-系列教程11:文档扫描OCR识别上(轮廓检测/轮廓近似/透视变换/OCR识别)项目实战、源码解读

🧡💛💚💙💜OpenCV实战系列总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 下篇内容: openCV实战-系列教程13:文档扫描OCR识别下&am…

李跳跳下载-《告别广告困扰,让李跳跳助力打造清爽浏览体验》

大家好,👋今天我想向大家介绍一款非常好用的应用程序——李跳跳 App 🚀。 随着智能手机的普及,应用程序已经成为了我们日常生活中必不可少的一部分。但是,随之而来的是各种各样的广告,这些广告不仅浪费我们…

【C++】输入输出及格式控制

在各类算法竞赛和机试中,对测试数据和输出格式往往会有明确的规定,笔者结合个人刷题经历,得到了以下C语言输入输出控制的方法。 cin:从缓冲区中读取数据 cin>>从缓冲区中读取数据时,若缓冲区中第一个字符是空格…

PXE网络批量装机

目录 一、什么是PXE? 二、PXE(Preboot Execution Environment)的主要组件 1、PXE服务器(PXE Server) 2、DHCP服务器(Dynamic Host Configuration Protocol Server) 3、TFTP服务器&#xff…

信号完整性分析基础知识之有损传输线、上升时间衰减和材料特性(四):有损传输线建模

传输线中信号衰减的两个损耗过程是通过信号和返回路径导体的串联电阻以及通过有损耗介电材料的分流电阻。这两个电阻器的电阻都与频率相关。 值得注意的是,理想电阻器的电阻随频率恒定。我们已经证明,在理想的有损传输线中,用于描述损耗的两个…

CAD 中Spline(样条曲线)的创建

我把自己研究的流程留下,读者需慢慢探索: Polyline pl new Polyline(); pl.AddVertexAt(0, new Point2d(2, 2), 0, 0, 0); pl.AddVertexAt(1, new Point2d(5, 5), 0, 0, 0); pl.AddVertexAt(2, new Point2d(10, 3), 0, 0, 0); pl.AddVertexAt(3, new Point2d(15, …

uniapp 布局(自定义导航栏加固定高度的主要内容)

不想让整体页面出现滚动条 页面大致分为三部分,导航栏、主题内容、tabbar,不想让整个页面出现滚动条,只想让主要内容滚动。 我这里是直接用了uni.getSystemInfoSync(),整体分为两部分,自定义头部和滚动内容&#xff…

UE5- c++ websocket客户端写法

# 实现目标 ue5 c 实现socket客户端,读取服务端数据,并进行解析 #实现步骤 {projectName}.Build.cs里增加 "WebSockets","JsonUtilities", "Json"配置信息,最终输出如下: using UnrealBuildTool;…

【SpringSecurity】九、Base64与JWT

文章目录 1、base64编码2、Base64Url3、JWT的产生背景4、JWT介绍5、JWT组成5.1 Header5.2 Payload5.3 Signature 6、JWT的使用方式7、JWT的几个特点 1、base64编码 base64是一种编码方式,不是加密方式。 所谓Base64,就是说选出64个字符:小写…