「Python入门」Python多进程

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
简介: 本文探讨Python中的单进程和多进程。多进程使用`multiprocessing`库,如`Process`类,类似于`threading.Thread`。进程是操作系统分配资源的基本单位,每个程序至少有一个进程。多进程允许多个任务并发执行,提升效率,尤其在多核CPU上优于多线程,因Python的GIL限制了多线程的并行计算。文中通过吃饭睡觉打豆豆的例子,展示了单进程按顺序执行,多进程则可并发执行。还介绍了带参数的多进程、获取进程ID、主进程等待子进程结束及子进程守护等概念。在IO或网络密集型任务中,多线程和多进程各有优势,具体选择应根据任务类型和资源需求。

@TOC


前言

本文主要介绍python单进程多进程。Python 要进行多进程操作,需要用到muiltprocessing库,其中的Process类跟threading模块的Thread类很相似。
进程是指一个程序在给定数据集合上的一次执行过程,是系统进行资源分配和运行调用的独立单位。可以简单地理解为操作系统中正在执行的程序。也就说,每个应用程序都有一个自己的进程。
每一个进程启动时都会最先产生一个线程,即主线程。然后主线程会再创建其他的子线程。python的多进程性能要明显优于多线程,因为cpythonGIL对性能做了约束。

在这里插入图片描述


一、 单进程

以吃饭睡觉打豆豆为例。单进程需要先吃饭,在睡觉,最后打豆豆,次序不可打乱。

# 单进程
import time
def eat():
    for i in range(3):
        print("吃饭……")
        time.sleep(1)

def sleep():
    for i in range(3):
        print("睡觉……")
        time.sleep(1)

def play():
    for i in range(3):
        print("打豆豆……")
        time.sleep(1)

if __name__ == '__main__':
    eat()
    sleep()
    play()

在这里插入图片描述

二、 多进程

以吃饭睡觉打豆豆为例。多进程对吃饭,睡觉,打豆豆,可以交叉进行,无需按序执行。

# 多进程
import multiprocessing # 导入进程包
import time
def eat():
    for i in range(3):
        print("吃饭……")
        time.sleep(1)

def sleep():
    for i in range(3):
        print("睡觉……")
        time.sleep(1)

def play():
    for i in range(3):
        print("打豆豆……")
        time.sleep(1)

if __name__ == '__main__':
    #target:指定函数名
    eat_process = multiprocessing.Process(target=eat) # 通过进程类创建进程对象
    sleep_process = multiprocessing.Process(target=sleep)
    play_process = multiprocessing.Process(target=play)

    eat_process.start()
    sleep_process.start()
    play_process.start()

在这里插入图片描述

三、 带参多进程

  • target:指定执行的函数名。此处注意,若只有一个元素,那个逗号也是不可以省略的。
  • args:使用元组方式给指定任务传参
  • kwargs:使用字典方式给指定任务传参
    ```java

    带参多进程

    import time
    import multiprocessing

def eat(num,name):
for i in range(num):
print(name+"吃饭……")
time.sleep(1)

def sleep(num,name):
for i in range(num):
print(name+"睡觉……")
time.sleep(1)

def play(num,name):
for i in range(num):
print(name+"打豆豆……")
time.sleep(1)

if name == 'main':

# target:指定执行的函数名。此处注意,若只有一个元素,那个逗号也是不可以省略的。
# args:使用元组方式给指定任务传参
# kwargs:使用字典方式给指定任务传参
eat_process = multiprocessing.Process(target=eat,args=(3,'vitian')) # 通过进程类创建进程对象
sleep_process = multiprocessing.Process(target=sleep,args=(3,'anna'))
play_process = multiprocessing.Process(target=play,args=(3,'prince'))

eat_process.start()
sleep_process.start()
play_process.start()

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/fedd765f33e344c69cfa7f310a3ed8b0.png)
# 四、 获取进程的编号
以吃饭睡觉打豆豆为例。主进程相同,子进程各不同。

```java
# 获取进程的编号
import time
import multiprocessing
import os


def eat(num,name):
    print("吃饭的进程ID:", os.getpid())
    print("吃饭的主进程ID:", os.getppid())
    for i in range(num):
        print(name+"吃饭……")
        time.sleep(1)


def sleep(num,name):
    print("睡觉的进程ID:", os.getpid())
    print("睡觉的主进程ID:", os.getppid())
    for i in range(num):
        print(name+"睡觉……")
        time.sleep(1)

def play(num,name):
    print("打豆豆的进程ID:", os.getpid())
    print("打豆豆的主进程ID:", os.getppid())
    for i in range(num):
        print(name+"打豆豆……")
        time.sleep(1)

if __name__ == '__main__':
    # target:指定执行的函数名
    # args:使用元组方式给指定任务传参
    # kwargs:使用字典方式给指定任务传参
    eat_process = multiprocessing.Process(target=eat,args=(3,'vitian')) # 通过进程类创建进程对象
    sleep_process = multiprocessing.Process(target=sleep,kwargs={"num": 2, "name":"anna"})
    play_process = multiprocessing.Process(target=play,args=(1,'prince'))
    print("主进程ID:", os.getpid())

    eat_process.start()
    sleep_process.start()
    play_process.start()

在这里插入图片描述

五、 主进程会等待所有的子进程执行结束再结束

# 主进程会等待所有的子进程执行结束再结束
import multiprocessing
import time


def eat():
    for i in range(10):
        print("吃饭睡觉打豆豆……")
        time.sleep(0.5)


if __name__ == '__main__':
    eat_process = multiprocessing.Process(target=eat)
    eat_process.start()

    time.sleep(1)
    print("主进程结束了……")

在这里插入图片描述

六、 子进程守护

设置子进程守护,当主进程结束时,子进程也不再继续执行,直接结束。
在这里插入图片描述

七、 多线程与单线程的取舍

多线程在IO密集型的操作下似乎也没有很大的优势(IO操作的任务再繁重一些就能体现出优势),在CPU密集型的操作下明显地比单线程线性执行性能更差,但是对于网络请求这种忙等阻塞线程的操作,多线程的优势便非常显著了。
多进程无论是在CPU密集型还是IO密集型以及网络请求密集型(经常发生线程阻塞的操作)中,都能体现出性能的优势。不过在类似网络请求密集型的操作上,与多线程相差无几,但却更占用CPU等资源,所以对于这种情况下,我们可以选择多线程来执行。

相关文章
|
2天前
|
机器学习/深度学习 数据可视化 数据挖掘
使用Python进行数据分析的入门指南
【9月更文挑战第33天】本文旨在为初学者提供一个关于使用Python进行数据分析的全面概述。我们将从基本的安装和设置开始,逐步介绍数据处理、数据可视化以及机器学习的基本概念和应用。文章将通过实际代码示例来展示如何使用Python及其相关库来解决常见的数据分析问题。
|
8天前
|
Python
Python 编程入门:打造你的第一个程序
【9月更文挑战第27天】编程,就像是在数字世界里绘画。想象一下,你手中的键盘是画笔,屏幕是画布,而代码则是你的颜料。这篇文章将带你走进编程的世界,学习如何使用 Python 这门语言来创建你的第一个程序。我们将从基础的语法开始,逐步深入到条件判断和循环结构,最终完成一个简单的猜数字游戏。无论你是否有编程经验,这里的内容都将为你打开一扇新的大门。
|
7天前
|
Python
? Python 装饰器入门:让代码更灵活和可维护
? Python 装饰器入门:让代码更灵活和可维护
12 4
|
7天前
|
数据可视化 Python
使用Python进行数据可视化:从入门到精通
【8月更文挑战第60天】本文是一篇面向初学者的Python数据可视化教程,旨在帮助读者掌握如何使用Python及其强大的库(如Matplotlib和Seaborn)来创建引人入胜的数据可视化。我们将从基础开始,逐步深入,最终达到能够独立完成复杂数据可视化项目的水平。无论你的背景如何,只要你对数据可视化感兴趣,这篇文章都将为你开启一段新的学习之旅。
|
8天前
|
Python
Python 装饰器入门:让代码更灵活和可维护
Python 装饰器入门:让代码更灵活和可维护
12 1
|
1天前
|
测试技术 数据安全/隐私保护 开发者
Python中的装饰器:从入门到精通
【9月更文挑战第34天】 在Python的世界里,装饰器是一个既强大又神秘的工具,它允许我们在不修改函数代码的情况下增加函数的功能。本文将通过浅显易懂的语言和实际的代码示例,带领读者从零开始理解装饰器的概念、原理和应用,直至能够熟练运用它来优化代码结构、增强代码可读性和提高开发效率。
8 0
|
6天前
|
数据采集 Linux 调度
Python之多线程与多进程
Python之多线程与多进程
12 0
|
3月前
|
运维 关系型数据库 MySQL
掌握taskset:优化你的Linux进程,提升系统性能
在多核处理器成为现代计算标准的今天,运维人员和性能调优人员面临着如何有效利用这些处理能力的挑战。优化进程运行的位置不仅可以提高性能,还能更好地管理和分配系统资源。 其中,taskset命令是一个强大的工具,它允许管理员将进程绑定到特定的CPU核心,减少上下文切换的开销,从而提升整体效率。
掌握taskset:优化你的Linux进程,提升系统性能
|
3月前
|
弹性计算 Linux 区块链
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
91 4
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
|
2月前
|
算法 Linux 调度
探索进程调度:Linux内核中的完全公平调度器
【8月更文挑战第2天】在操作系统的心脏——内核中,进程调度算法扮演着至关重要的角色。本文将深入探讨Linux内核中的完全公平调度器(Completely Fair Scheduler, CFS),一个旨在提供公平时间分配给所有进程的调度器。我们将通过代码示例,理解CFS如何管理运行队列、选择下一个运行进程以及如何对实时负载进行响应。文章将揭示CFS的设计哲学,并展示其如何在现代多任务计算环境中实现高效的资源分配。
下一篇
无影云桌面