前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【从零学习python 】83. Python多进程编程与进程池的使用

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

作者头像
全栈若城
发布2024-02-29 20:29:16
1460
发布2024-02-29 20:29:16
举报
文章被收录于专栏:若城技术专栏若城技术专栏

创建进程

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

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

代码语言:javascript
复制
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(进程号)。

示例:

代码语言:javascript
复制
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上执行,这会占用很大的空间。

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

代码语言:javascript
复制
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()

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

代码语言:javascript
复制
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()`本身就是一个阻塞方法

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

代码语言:javascript
复制
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()

进程间不能共享全局变量

代码语言:javascript
复制
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))

运行结果:

代码语言:javascript
复制
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]
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-02-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建进程
    • 说明
      • 方法说明
      • Pool
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档