一.进程

本文详细介绍了Python中的进程,包括进程概念、多进程使用、进程编号获取、带参数任务执行、守护进程设置及进程数据共享。通过示例代码展示了如何创建、管理和共享数据,以及使用进程池进行任务调度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.进程

1.什么是进程

在python程序中,想要实现多任务可以使用进程来完成,进程是实现多任务的一种方式.

2.进程的概念

一个正在运行的程序或者软件就是一个进程,它是操作系统进行资源分配的基本单位,也就是说每启动一个进程,操作系统都会给其分配一定的运行资源(内存资源)保证进程的运行。

3.进程的作用

多进程可以完成多任务,每个进程就好比一家独立的公司,每个公司都各自在运营,每个进程也在各自运行,执行各自的任务.

4.小结

1.进程使操作系统进行资源分配得基本单位
2.进程使python程序中实现多任务的一种方式

二.多进程的使用

1.导入进程包

#导入进程包
import multiprocessing

2.Process进程类的说明

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

group:指定进程组,目前只能使用None
target:执行的目标任务名
name:进程名字
args:以元组方式给执行任务传参
kwargs:以字典方式给执行任务传参
Process创建的实例对象的常用方法:

start():启动子进程实例(创建子进程)
join():等待子进程执行结束
Process创建的实例对象的常用属性:

name:当前进程的别名,默认为Process-N,N为从1开始递增的整数

3.多进程完成多任务的代码

import multiprocessing
import time


# 跳舞任务
def dance():
    for i in range(5):
        print("跳舞中...")
        time.sleep(0.2)


# 唱歌任务
def sing():
    for i in range(5):
        print("唱歌中...")
        time.sleep(0.2)

if __name__ == '__main__':
    # 创建跳舞的子进程
    # target: 表示执行的目标任务名(函数名、方法名)
    dance_process = multiprocessing.Process(target=dance)
    sing_process = multiprocessing.Process(target=sing)

    # 启动子进程执行对应的任务
    dance_process.start()
    sing_process.start()

4.小结

1.导入进程包
import multiprocessing
2.创建子进程并指定执行的任务
sub_process = multiprocessing.Process(target = 任务名)
3.启动进程执行任务
sub_process.start()

三.获取进程编号

1.获取进程编号的目的

获取进程编号的目的是验证主进程和子进程的关系,可以得知子进程是有哪个主进程创建出来的.
.获取当前进程编号
.获取当前父进程编号

2.获取当前进程编号

代码:

import multiprocessing
import time
import os


# 跳舞任务
def dance():
    # 获取当前进程的编号
    print("dance:", os.getpid())
    # 获取当前进程
    print("dance:", multiprocessing.current_process())
    for i in range(5):
        print("跳舞中...")
        time.sleep(0.2)
        # 扩展:根据进程编号杀死指定进程
        os.kill(os.getpid(), 9)


# 唱歌任务
def sing():
    # 获取当前进程的编号
    print("sing:", os.getpid())
    # 获取当前进程
    print("sing:", multiprocessing.current_process())
    for i in range(5):
        print("唱歌中...")
        time.sleep(0.2)


if __name__ == '__main__':

    # 获取当前进程的编号
    print("main:", os.getpid())
    # 获取当前进程
    print("main:", multiprocessing.current_process())
    # 创建跳舞的子进程
    # group: 表示进程组,目前只能使用None
    # target: 表示执行的目标任务名(函数名、方法名)
    # name: 进程名称, 默认是Process-1, .....
    dance_process = multiprocessing.Process(target=dance, name="myprocess1")
    sing_process = multiprocessing.Process(target=sing)

    # 启动子进程执行对应的任务
    dance_process.start()
    sing_process.start()

3.获取当前父进程编号

os.getppiid()表示获取当前父进程编号
代码:

import multiprocessing
import time
import os


# 跳舞任务
def dance():
    # 获取当前进程的编号
    print("dance:", os.getpid())
    # 获取当前进程
    print("dance:", multiprocessing.current_process())
    # 获取父进程的编号
    print("dance的父进程编号:", os.getppid())
    for i in range(5):
        print("跳舞中...")
        time.sleep(0.2)
        # 扩展:根据进程编号杀死指定进程
        os.kill(os.getpid(), 9)


# 唱歌任务
def sing():
    # 获取当前进程的编号
    print("sing:", os.getpid())
    # 获取当前进程
    print("sing:", multiprocessing.current_process())
    # 获取父进程的编号
    print("sing的父进程编号:", os.getppid())
    for i in range(5):
        print("唱歌中...")
        time.sleep(0.2)


if __name__ == '__main__':

    # 获取当前进程的编号
    print("main:", os.getpid())
    # 获取当前进程
    print("main:", multiprocessing.current_process())
    # 创建跳舞的子进程
    # group: 表示进程组,目前只能使用None
    # target: 表示执行的目标任务名(函数名、方法名)
    # name: 进程名称, 默认是Process-1, .....
    dance_process = multiprocessing.Process(target=dance, name="myprocess1")
    sing_process = multiprocessing.Process(target=sing)

    # 启动子进程执行对应的任务
    dance_process.start()
    sing_process.start()
main: 70860
main: <_MainProcess(MainProcess, started)>
dance: 70861
dance: <Process(myprocess1, started)>
dance的父进程编号: 70860
跳舞中...
sing: 70862
sing: <Process(Process-2, started)>
sing的父进程编号: 70860
唱歌中...
唱歌中...
唱歌中...
唱歌中...
唱歌中...

小结

1.获取当前进程编号
.os.getpid()
2.获取当前父进程编号
.os’.getppid()
3.获取进程编号可以查看父子进程的关系

四.进程执行带有参数的任务

1.进程执行带有参数任务的介绍

Process类执行任务并给任务传参数有两种方式
1.args 表示以元组的方式给执行任务传参
2.kwargs表示以字典方式给执行任务传参

2.args参数使用

代码:

import multiprocessing
import time


# 带有参数的任务
def task(count):
    for i in range(count):
        print("任务执行中..")
        time.sleep(0.2)
    else:
        print("任务执行完成")


if __name__ == '__main__':
    # 创建子进程
    # args: 以元组的方式给任务传入参数
    sub_process = multiprocessing.Process(target=task, args=(5,))
    sub_process.start()

3.kwargs参数的使用

代码:

import multiprocessing
import time


# 带有参数的任务
def task(count):
    for i in range(count):
        print("任务执行中..")
        time.sleep(0.2)
    else:
        print("任务执行完成")


if __name__ == '__main__':
    # 创建子进程

    # kwargs: 表示以字典方式传入参数
    sub_process = multiprocessing.Process(target=task, kwargs={"count": 3})
    sub_process.start()

4.小结

1进程执行任务并传参有两种方式
.元组方式传参(args):元组方式传参一定要和参数的顺序保持一致.
.字典方式传参(kwargs):字典方式传参字典中的key一定要和参数名保持一致.

五.守护进程

1.什么守护进程

设置守护主进程的目的是主进程退出子进程销毁,不让主进程再等待子进程去执行.

2.设置守护进程方式

子进程对象.daemon = True

代码

import time
from multiprocessing import Process

def run1():
    print('run1')
    time.sleep(1)


def run2():
    print('run2')
    time.sleep(2)


if __name__ == '__main__':

    p1 = Process(target=run1)
    p2 = Process(target=run2)

    p1.daemon = True
    p2.daemon = True

    p1.start()
    p2.start()

六.进程数据共享

1.进程间的数据不共享

代码

import time
from multiprocessing import Process

data = []

def run1():
    data.append('run1')


def run2():
    data.append('run2')


if __name__ == '__main__':

    p1 = Process(target=run1)
    p2 = Process(target=run2)

    p1.start()
    p2.start()

    p1.join()
    p2.join()

    print(data)

2.进程间的数据共享的三种方式

1.管理器 manager
代码

from multiprocessing import Process, Manager

def run1(lis):
    lis.append('run1')

def run2(lis):
    lis.append('run2')



if __name__ == '__main__':

    with Manager() as manager:

        lis = manager.list()

        p1 = Process(target=run1, args=(lis,))
        p2 = Process(target=run2, args=(lis,))

        p1.start()
        p2.start()

        p1.join()
        p2.join()

        print(lis)

2.队列 queue
代码

import time
from multiprocessing import Process, Queue

def run1(q):
    q.put('run1')
    time.sleep(1)
    print('run1中获取:%s ' % q.get())

def run2(q):
    print('run2中获取:%s ' % q.get())
    q.put('run2')



if __name__ == '__main__':

    q = Queue()

    p1 = Process(target=run1, args=(q,))
    p2 = Process(target=run2, args=(q,))

    p1.start()
    p2.start()

    p1.join()
    p2.join()

3.管道pipe

import time
from multiprocessing import Process, Pipe

def run1(obj1):
    obj1.send('run1')
    time.sleep(1)
    print('run1中获取:%s ' % obj1.recv())

def run2(obj2):
    print('run2中获取:%s ' % obj2.recv())
    obj2.send('run2')

if __name__ == '__main__':

    obj1, obj2 = Pipe()

    p1 = Process(target=run1, args=(obj1,))
    p2 = Process(target=run2, args=(obj2,))

    p1.start()
    p2.start()

    p1.join()
    p2.join()

七.进程池

1.为什么要采用进程池

当需要创建的子进程数量不多时,可以使用multiprocessing的Process动态生成多个进程,但是如果是上千个上百个,手动去创建的话就显得任务非常繁重,而且频繁的创建和销毁,会消耗非常大的资源,所以就可以用到multiprocessing模块提供的Pool方法.

2.设置进程池

初始化Pool时,可以指定一个做大进程数,当有新的请求提交到Pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果进程池中的进程数量已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来执行.
代码:

import os
import time
from multiprocessing import Pool


def worker(msg):
    print("%s开始执行,进程号为%d" % (msg, os.getpid()))
    time.sleep(1)


po = Pool(3)  # 定义一个进程池,最大进程数3
for i in range(0, 10):
    # Pool.apply_async(要调用的目标,(传递给目标的参数元祖,))
    # 每次循环将会用空闲出来的子进程去调用目标
    po.apply_async(worker, (i,))

po.close()  # 关闭进程池,关闭后po不再接收新的请求
po.join()  # 等待po中所有子进程执行完成,必须放在close语句之后
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值