【从零学习python 】83. Python多进程编程与进程池的使用

简介: 【从零学习python 】83. Python多进程编程与进程池的使用

创建进程

multiprocessing模块就是跨平台版本的多进程模块,提供了一个Process类来代表一个进程对象,这个对象可以理解为是一个独立的进程,可以执行另外的事情。

示例:创建一个进程,执行两个死循环。

from multiprocessing import Process
import time
def run_proc():
    """子进程要执行的代码"""
    while True:
        print("----2----")
        time.sleep(1)
if __name__=='__main__':
    p = Process(target=run_proc)
    p.start()
    while True:
        print("----1----")
        time.sleep(1)

说明

创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动。

方法说明

Process(target [, name [, args [, kwargs]]])

  • target:如果传递了函数的引用,可以任务这个子进程就执行这里的代码。
  • args:给target指定的函数传递的参数,以元组的方式传递。
  • kwargs:给target指定的函数传递命名参数。
  • name:给进程设定一个名字,可以不设定。

Process创建的实例对象的常用方法:

  • start():启动子进程实例(创建子进程)。
  • is_alive():判断进程子进程是否还在活着。
  • join([timeout]):是否等待子进程执行结束,或等待多少秒。
  • terminate():不管任务是否完成,立即终止子进程。

Process创建的实例对象的常用属性:

  • name:当前进程的别名,默认为Process-NN为从1开始递增的整数。
  • pid:当前进程的pid(进程号)。

示例:

from multiprocessing import Process
import os
from time import sleep
def run_proc(name, age, **kwargs):
    for i in range(10):
        print('子进程运行中,name= %s,age=%d ,pid=%d...' % (name, age, os.getpid()))
        print(kwargs)
        sleep(0.2)
if __name__=='__main__':
    p = Process(target=run_proc, args=('test',18), kwargs={"m":20})
    p.start()
    sleep(1)  # 1秒中之后,立即结束子进程
    p.terminate()
    p.join()

Pool

开启过多的进程并不能提高你的效率,反而会降低你的效率,假设有500个任务,同时开启500个进程,这500个进程除了不能一起执行之外(CPU没有那么多核),操作系统调度这500个进程,让他们平均在4个或8个CPU上执行,这会占用很大的空间。

如果要启动大量的子进程,可以用进程池的方式批量创建子进程:

def task(n):
    print('{}----->start'.format(n))
    time.sleep(1)
    print('{}------>end'.format(n))
if __name__ == '__main__':
    p = Pool(8)  # 创建进程池,并指定进程池的个数,默认是CPU的核数
    for i in range(1, 11):
        # p.apply(task, args=(i,))  # 同步执行任务,一个一个地执行任务,没有并发效果
        p.apply_async(task, args=(i,))  # 异步执行任务,可以达到并发效果
    p.close()
    p.join()

进程池获取任务的执行结果:

def task(n):
    print('{}----->start'.format(n))
    time.sleep(1)
    print('{}------>end'.format(n))
    return n ** 2
if __name__ == '__main__':
    p = Pool(4)
    for i in range(1, 11):
        res = p.apply_async(task, args=(i,))  # `res` 是任务的执行结果
        print(res.get())  # 直接获取结果的弊端是,多任务又变成同步的了
    p.close()
    # p.join()  不需要再`join`了,因为 `res.get()`本身就是一个阻塞方法

异步获取进程的执行结果:

import time
from multiprocessing.pool import Pool
def task(n):
    print('{}----->start'.format(n))
    time.sleep(1)
    print('{}------>end'.format(n))
    return n ** 2
if __name__ == '__main__':
    p = Pool(4)
    res_list = []
    for i in range(1, 11):
        res = p.apply_async(task, args=(i,))
        res_list.append(res)  # 使用列表来保存进程执行结果
    for re in res_list: 
        print(re.get())
    p.close()

进程间不能共享全局变量

from multiprocessing import Process
import os
nums = [11, 22]
def work1():
    """子进程要执行的代码"""
    print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
    for i in range(3):
        nums.append(i)
        print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
def work2():
    """子进程要执行的代码"""
    nums.pop()
    print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))
if __name__ == '__main__':
    p1 = Process(target=work1)
    p1.start()
    p1.join()
    p2 = Process(target=work2)
    p2.start()
    print('in process0 pid={} ,nums={}'.format(os.getpid(),nums))

运行结果:

in process1 pid=2707 ,nums=[11, 22]
in process1 pid=2707 ,nums=[11, 22, 0]
in process1 pid=2707 ,nums=[11, 22, 0, 1]
in process1 pid=2707 ,nums=[11, 22, 0, 1, 2]
in process0 pid=2706 ,nums=[11, 22]
in process2 pid=2708 ,nums=[11]
相关文章
|
3天前
|
数据采集 SQL 关系型数据库
Python学习路线【对标大厂Python开发工程师的招聘要求,并推荐优质免费资源】打卡学习不迷茫
Python学习路线【对标大厂Python开发工程师的招聘要求,并推荐优质免费资源】打卡学习不迷茫
30 14
|
1天前
|
索引 Python
十分钟学习Python异常处理
在编程过程中,错误和异常是不可避免的。Python提供了强大的异常处理机制,帮助我们捕获和处理运行时错误,使程序更加健壮和可靠。本文将带你在十分钟内快速掌握Python的异常处理基础知识。
|
2天前
|
机器学习/深度学习 算法 数据挖掘
Python强化学习应用于数据分析决策策略:** - 强化学习让智能体通过环境互动学习决策。
【7月更文挑战第5天】**Python强化学习应用于数据分析决策策略:** - 强化学习让智能体通过环境互动学习决策。 - Python因丰富库(如TensorFlow, PyTorch, Keras, Pandas, NumPy)和生态而受青睐。 - 使用OpenAI Gym构建环境,如`gym.make('CartPole-v0')`。 - 选择模型,例如神经网络,定义策略如Q-Learning。 - 训练模型,调整智能体行为,如Q-Learning更新Q表。 - 最后评估模型性能,实现数据驱动决策。
11 3
|
1天前
|
存储 人工智能 数据挖掘
十分钟学习Python基础知识
Python是一种高效、易学且功能强大的编程语言,广泛应用于数据分析、人工智能、Web开发等领域。如果你是编程新手,想要快速入门Python,那么这篇文章将是你的最佳选择。我将在十分钟内带你了解Python的基础知识。
|
4天前
|
存储 安全 编译器
Python学习日记(一:List、Tuple、dictionary)
1.列表、元组和字典都是序列 2.列表字典可以修改和删除序列中的某个元素,而元组就是一个整体,不能修改和删除,一定要修改或删除的话,只能修改和删除整个元组。 3.既然元组不能删除和修改,有什么作用呢? 1.元组比列表遍历速度快,因为元组是一个整体,运算效率高; 2.正是因为不能修改,元组可以保护不需要修改的数据,可以使代码结构更安全。
|
4天前
|
API Python
Python学习日记(二:函数和逻辑操作)
Python中的函数和逻辑操作至关重要。函数包括可变和不可变参数。
|
4天前
|
机器学习/深度学习 TensorFlow 算法框架/工具
使用Python实现深度学习模型:迁移学习与领域自适应教程
【7月更文挑战第3天】 使用Python实现深度学习模型:迁移学习与领域自适应教程
7 0
|
2月前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
13天前
|
Python
Python多进程编程详细剖析
Python多进程编程详细剖析
16 3
|
29天前
|
安全 开发者 Python
Python中的多线程与多进程编程
Python作为一种广泛使用的编程语言,在处理并发性能时具有独特的优势。本文将深入探讨Python中的多线程与多进程编程技术,分析其原理和应用,帮助读者更好地理解并发编程在Python中的实现与优化。