【python中的多进程了解一下?】

在这里插入图片描述

基本说明

多进程是指在同一台计算机中同时运行多个独立的进程。每个进程都有自己的地址空间,可用于执行一些特定的任务。这些进程可以同时执行,从而提高了程序的性能和效率。多进程可以在多核计算机上实现真正的并行计算,可以同时运行多个程序,从而大大提高了计算机的利用率。

在多进程编程中,进程之间是独立的,它们各自运行自己的程序,有自己的地址空间和系统资源,不会相互干扰。每个进程都有自己的PID(进程标识符),它是一个唯一的标识符,用于在系统中识别该进程。多进程可以通过IPC(进程间通信)来实现数据共享和通信。

Python的多进程模块multiprocessing提供了一种方便的方法来创建和管理多个进程。它可以在单个Python解释器中创建多个进程,从而实现并行计算。multiprocessing模块还提供了一些方便的功能,如进程池、进程通信和共享内存等。

多进程编程可以在很多场景中提高程序的运行效率,如CPU密集型任务、I/O密集型任务、并行计算、大规模数据处理和机器学习等。但需要注意多进程之间的数据同步和通信,以避免数据竞争和死锁等问题。

import multiprocessing
from PIL import Image, ImageFilter

def process_image(filename, size, q):
    """使用高斯模糊对图像进行处理"""
    img = Image.open(filename)
    img = img.resize(size)
    img = img.filter(ImageFilter.GaussianBlur(radius=5))
    q.put(img)

if __name__ == '__main__':
    filenames = ["image1.jpg", "image2.jpg", "image3.jpg"]
    size = (800, 800)
    q = multiprocessing.Queue()
    processes = []
    for filename in filenames:
        p = multiprocessing.Process(target=process_image, args=(filename, size, q))
        processes.append(p)
        p.start()
    for p in processes:
        p.join()
    images = []
    while not q.empty():
        images.append(q.get())
    for i, img in enumerate(images):
        img.save(f"processed_image_{i}.jpg")

这个程序使用多进程对多个图像进行处理。它将每个图像分配给一个进程来进行处理,并使用队列将处理后的图像收集起来。在这个例子中,我们对每个图像进行了大小调整和高斯模糊,然后将它们保存在磁盘上。

import multiprocessing
import requests
from bs4 import BeautifulSoup

def scrape_page(url, q):
    """从网页中提取信息"""
    r = requests.get(url)
    soup = BeautifulSoup(r.content, 'html.parser')
    title = soup.title.string
    q.put((url, title))

if __name__ == '__main__':
    urls = ["http://www.example.com", "http://www.example.org", "http://www.example.net"]
    q = multiprocessing.Queue()
    processes = []
    for url in urls:
        p = multiprocessing.Process(target=scrape_page, args=(url, q))
        processes.append(p)
        p.start()
    for p in processes:
        p.join()
    results = []
    while not q.empty():
        results.append(q.get())
        for url, title in results:
       		print(f"{url}: {title}")

这个程序使用多进程来爬取多个网页的标题。它将每个URL分配给一个进程来处理,并使用队列将提取的标题收集起来。在这个例子中,我们使用requestsBeautifulSoup库来获取和解析网页。

进程间通信

Python的多进程模块multiprocessing提供了多种进程间通信的方式,包括:

  1. 队列(Queue):队列是最常用的进程间通信方式之一,它是线程安全的,可以在多个进程之间共享数据。可以使用multiprocessing.Queue类来创建一个队列,进程之间可以使用put()get()方法向队列中添加和获取数据。

    import multiprocessing
    
    def producer(q):
        for i in range(5):
            q.put(i)
        q.put(None)
    
    def consumer(q):
        while True:
            item = q.get()
            if item is None:
                break
            print(f"Consumed {item}")
    
    if __name__ == '__main__':
        q = multiprocessing.Queue()
        p1 = multiprocessing.Process(target=producer, args=(q,))
        p2 = multiprocessing.Process(target=consumer, args=(q,))
        p1.start()
        p2.start()
        p1.join()
        p2.join()
    

    需要注意的是,在队列中添加一个特殊的值(如None)可以用来表示队列的结束。在这个示例中,生产者进程在添加完所有数据后,向队列中添加了一个None,表示队列已经结束。消费者进程在获取到None时,就知道队列已经结束,可以退出循环。

  2. 管道(Pipe):管道是另一种进程间通信方式,它可以在两个进程之间传递数据。可以使用multiprocessing.Pipe()函数创建一个管道,它返回两个连接对象,每个连接对象可以用于向另一个进程发送数据。

    import multiprocessing
    
    def send_data(conn):
        data = [1, 2, 3, 4, 5]
        conn.send(data)
        conn.close()
    
    def receive_data(conn):
        data = conn.recv()
        print(f"Received data: {data}")
        conn.close()
    
    if __name__ == '__main__':
        parent_conn, child_conn = multiprocessing.Pipe()
        p1 = multiprocessing.Process(target=send_data, args=(child_conn,))
        p2 = multiprocessing.Process(target=receive_data, args=(parent_conn,))
        p1.start()
        p2.start()
        p1.join()
        p2.join()
    

    在这个示例中,我们创建了两个进程,一个发送进程和一个接收进程。发送进程向管道中发送一些数据,接收进程从管道中接收数据并进行处理。

    在这个示例中,我们使用multiprocessing.Pipe()函数创建了一个管道,并将其分别传递给发送进程和接收进程。发送进程使用send()方法将数据发送到管道中,接收进程使用recv()方法从管道中接收数据。

    需要注意的是,管道是双向的,每个管道有两个连接对象,分别表示管道的两端。在这个示例中,我们使用multiprocessing.Pipe()函数创建了一个管道,并将其分别传递给发送进程和接收进程。管道的两个连接对象都可以用于发送和接收数据。

    在实际应用中,管道通常被用来进行进程之间的数据传递和协调,例如,我们可以将一个大型任务拆分成多个小任务,并将这些小任务分配给多个进程来处理。在处理完成后,这些进程可以使用管道来将结果传递给主进程,主进程可以将这些结果合并并进行汇总。

    需要注意的是,管道通常比队列更快,但它只适用于两个进程之间的通信。如果需要进行多个进程之间的通信,应该使用队列或其他进程间通信方式。

  3. 共享内存(Value和Array):共享内存是一种特殊的进程间通信方式,它可以在多个进程之间共享数据。multiprocessing模块提供了ValueArray类来实现共享内存,Value用于存储单个值,Array用于存储多个值。

    import multiprocessing
    
    def modify_value(val, lock):
        with lock:
            val.value += 1
    
    def modify_array(arr, lock):
        with lock:
            for i in range(len(arr)):
                arr[i] *= 2
    
    if __name__ == '__main__':
        val = multiprocessing.Value('i', 0)
        arr = multiprocessing.Array('i', [1, 2, 3, 4, 5])
        lock = multiprocessing.Lock()
    
        p1 = multiprocessing.Process(target=modify_value, args=(val, lock))
        p2 = multiprocessing.Process(target=modify_array, args=(arr, lock))
        p1.start()
        p2.start()
        p1.join()
        p2.join()
    
        print(f"Value: {val.value}")
        print(f"Array: {arr[:]}")
    
    

    在这个示例中,我们创建了一个共享整数对象、一个共享数组对象和一个锁对象。在进程修改共享内存对象的值时,我们使用了with lock:语句来获取锁对象,以保证对共享内存对象的访问的同步和互斥。在修改完成后,锁会自动释放,以便其他进程可以继续访问共享内存对象。

    需要注意的是,在使用锁时,要尽可能地减小锁的粒度,避免出现死锁或性能问题。在实际应用中,共享内存通常被用来存储一些常用的数据,例如,程序配置信息、缓存数据等。共享内存通常比其他进程间通信方式更快,但由于数据共享的原因,也更容易出现问题。

  4. 锁(Lock):在多个进程之间共享数据时,需要使用锁来防止数据竞争。可以使用multiprocessing.Lock类来创建一个锁对象,进程可以使用acquire()release()方法来获取和释放锁。

    import multiprocessing
    
    def increment_counter(counter, lock):
        for i in range(1000):
            with lock:
                counter.value += 1
    
    if __name__ == '__main__':
        counter = multiprocessing.Value('i', 0)
        lock = multiprocessing.Lock()
    
        processes = []
        for i in range(5):
            p = multiprocessing.Process(target=increment_counter, args=(counter, lock))
            processes.append(p)
            p.start()
    
        for p in processes:
            p.join()
    
        print(f"Counter value: {counter.value}")
    
    

    在这个示例中,我们创建了一个共享整数对象counter和一个锁对象lock。进程可以使用with lock:语句来获取锁对象,以保证对共享内存对象的访问的同步和互斥。在修改完成后,锁会自动释放,以便其他进程可以继续访问共享内存对象。

    在这个示例中,我们创建了5个进程,并将它们添加到进程列表中。每个进程都会执行increment_counter()函数,该函数使用with lock:语句获取锁对象,并将共享整数对象counter加1。在执行完成后,锁会自动释放。

    需要注意的是,在使用锁时,要尽可能地减小锁的粒度,避免出现死锁或性能问题。在实际应用中,锁通常被用来保护共享数据的读写操作,以避免数据竞争和死锁等问题。

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

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

相关文章

工程行业管理系统-专业的工程管理软件-提供一站式服务

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下: 首页 工作台:待办工作、消息通知、预警信息,点击可进入相应的列表 项目进度图表:选择(总体或单个)项目显示…

RabbitMQ:消息中间件

文章目录 概念管理界面简介4中常见交换器类型1.Direct交换器:2.Fanout交换器3.Topic交换器4.headers交换器 对象类型消息传递同步等待使用代码创建队列待续...... 概念 在微服务架构中项目之间项目A调用项目B 项目B调用项目C项目C调用项目D。。 用户必须等待项目之间内容依次的…

Linux:centos:系统服务基础控制(systemctl)基础使用 图形化工具ntsysv使用

基础使用的办法为: systemctl控制类型服务名称 控制常用类型为一下几个 start 启动 stop 停止 enable 开机自启 disable 开机不自启 restart 重新启动 reload 重新加载 status 查看服务状态 systemc…

智加科技与舍弗勒签订商用车先进转向系统量产合作协议,将率先量产行业首个正向开发的智能重卡冗余转向

自动驾驶已经成为当前汽车行业的重要发展趋势之一。在此背景下,在2023上海国际汽车展期间,智加科技与舍弗勒集团签订量产合作协议,双方将在自动驾驶商用车先进转向系统领域展开合作,共同推动重卡自动驾驶的技术应用和创新发展。 图…

死锁---银行家算法例题

1、知识点 1.银行家算法使用的四个必要的数据结构是: 可用资源向量Available,最大需求矩阵Max,分配矩阵Allocation,需求矩阵Need。 2.银行家算法是不是破坏了产生死锁的必要条件来达到避免死锁的目的?若是,请简述破…

浅析商场智能导购系统功能与实施效益

商场智能导购系统是一种基于物联网技术和人工智能算法的解决方案,旨在提供商场内部的智能导购服务,为消费者提供个性化的购物导引和推荐,提升用户购物体验,增加商场的客流量和销售额。 商场智能导购系统的方案一般包括以下主要功能…

初识 MongoDB

文章目录 一、简介二、体系结构三、数据类型四、特点五、应用场景 提示:以下是本篇文章正文内容,MongoDB 系列学习将会持续更新 一、简介 MongoDB 是一个文档数据库,是由字段和值对(field:value)组成的数据结构&…

同态随机基加密的量子多方密码-数学公式

众所周知,信息和信息处理的完全量子理论提供了诸多好处,其中包括一种基于基础物理的安全密码学,以及一种实现量子计算机的合理希望,这种计算机可以加速某些数学问题的解决。这些好处来自于独特的量子特性,如叠加、纠缠…

第一节 法学

目录 法学的概念法学的性质 实践性构成了法学的学问性质 法学的研究对象 1.法律制度问题(X法律制度)2. 社会现实或社会生活关系问题 (Y社会现实/社会关系)3.法律制度与社会现实之间如何对应的问题 (Yf(x) f为什么函数) 法学的概…

耗时半月,终于把牛客网上的软件测试面试八股文整理成了PDF合集(测试基础+linux+MySQL+接口测试+自动化测试+测试框架+jmeter测试+测试开发)

大家好,最近有不少小伙伴在后台留言,近期的面试越来越难了,要背的八股文越来越多了,考察得越来越细,越来越底层,明摆着就是想让我们徒手造航母嘛!实在是太为难我们这些程序员了。 这不&#xf…

shell中的for循环和if判断

一.编写脚本for1.sh,使用for循环创建20账户,账户名前缀由用户从键盘输入,账户初始密码由用户输入,例如: test1、test2、test3、.....、 test10 1.创建脚本for1.sh [rootserver ~]# vim for1.sh 2.编写脚本for1.sh 3.执行脚本for1.sh [roo…

fzyczn生日赛t1 CZN

fzy&czn生日赛t1 CZN 膜拜hybb首杀 文章目录 fzy&czn生日赛t1 CZN题目背景题目描述分析my codewnags code 题目 题目背景 有一天,czn在机房里面心心念念的pj终于来找他了,pj希望czn能够帮助她来解决一道数学题,czn“十分不乐意”地…

Spring入门案例--bean基础配置

bean基础配置(id与class) 对于bean的基础配置&#xff0c;在前面的案例中已经使用过: 1 <bean id"" class""/> 其中&#xff0c;bean标签的功能、使用方式以及id和class属性的作用&#xff0c;我们通过一张图来描述下 这其中需要大家重点掌握的…

Linux应用编程(进程)

一、进程与程序 注册进程终止处理函数 atexit() #include <stdlib.h> int atexit(void (*function)(void));使用该函数需要包含头文件<stdlib.h>。 函数参数和返回值含义如下&#xff1a; function&#xff1a;函数指针&#xff0c;指向注册的函数&#xff0c;此…

leetcode160. 相交链表

给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回结果后&…

软件测试工程师需要达到什么水平才能顺利拿到 20k 无压力?

最近有粉丝朋友问&#xff1a;软件测试员需要达到什么水平才能顺利拿到 20k 无压力&#xff1f; 这里写一篇文章来详细说说&#xff1a; 目录 扎实的软件测试基础知识&#xff1a;具备自动化测试经验和技能&#xff1a;熟练掌握编程语言&#xff1a;具备性能测试、安全测试、全…

flv怎么无损转换成mp4格式,3大超级方法分享

flv格式是目前在视频分享媒体播放网站上广泛使用的一种视频文件格式&#xff0c;可以在网站窗口中直接播放&#xff0c;这类视频文件还能够有效保护版权。但是有些时候我们可能需要将flv格式的视频转换为其他格式&#xff0c;比如mp4。但是该怎么操作呢&#xff1f; 其实有很多…

【花雕学AI】深度挖掘ChatGPT角色扮演的一个案例—CHARACTER play : 莎士比亚

CHARACTER play : 莎士比亚 : 52岁&#xff0c;男性&#xff0c;剧作家&#xff0c;诗人&#xff0c;喜欢文学&#xff0c;戏剧&#xff0c;爱情 : 1、问他为什么写《罗密欧与朱丽叶》 AI: 你好&#xff0c;我是莎士比亚&#xff0c;一位英国的剧作家和诗人。我很高兴你对我的…

【状态估计】用于描述符 LTI 和 LPV 系统的分析、状态估计和故障检测的算法(Matlab代码实现)

&#x1f4a5; &#x1f4a5; &#x1f49e; &#x1f49e; 欢迎来到本博客 ❤️ ❤️ &#x1f4a5; &#x1f4a5; &#x1f3c6; 博主优势&#xff1a; &#x1f31e; &#x1f31e; &#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 …

一文看懂数据云平台的“可观测性”技术实践

背景 这是一家大型制造集团。为监控及预测工厂设备运行情况&#xff0c;IT部门在数据云平台DataSimba上按天执行数据作业&#xff0c;每24小时对工厂设备的日志数据进行分析&#xff0c;发现能对业务起到很好的辅助作用&#xff0c;效果不错。 “要不升级为每1个小时跑一次&am…