39.python之创建进程

进程概念

进程

  • 进程是程序的一次执行过程,是一个动态概念,是程序在执行过程中分配和管理资源的基本单位,每一个进程都有一个自己的地址空间,至少有 5 种基本状态,它们是:初始态,执行态,等待状态,就绪状态,终止状态。
  • 例如每打开一个软件,或者每执行一个python脚本都是启动一个进程
  • 启动进程会占用cpu和内存

多进程

  • 就是同时启动多个软件(进程)
  • 例如手机系统启动多个软件,手机系统属于主进程,启动的多个软件属于子进程
  • 多个进程同时在执行程序时,他们之间互不干扰,各自执行自己的业务逻辑

进程的创建模块:模块multiprocessing的Process类

创建进程:

from multiprocessing import Process
p = Process(target,args,kwargs,name,group)

或者:
    
import multiprocessing
p = multiprocessing.Process(target,args,kwargs,name,group)

参数:

  • target:表示这个进程实例所调用对象;
  • args:表示调用对象的位置参数元组;
  • kwargs:表示调用对象的关键字参数字典;
  • name:为当前进程实例的别名;
  • group:大多数情况下用不到;

创建进程的2种方式

方式1:通过Process类可以创建一个进程对象,然后使用start开启进程

import os
import multiprocessing

def test1():
    print(f'test1,进程号是:{os.getpid()}')
def test2(name, age, like):
    print(f'test2,name={name},age={age},like={like},进程号是:{os.getpid()}')

if __name__ == '__main__':
    t1 = multiprocessing.Process(target=test1)
    t1.start()
    t2 = multiprocessing.Process(target=test2, args=('张三', 18, '跑步'))
    t2.start()

结果:
在这里插入图片描述

方式2:
通过子类继承Process类,子类中必须有run方法,里面实现进程功能
创建实例化对象后,调用对象的start方法,会执行run中的代码

import os
from multiprocessing import Process

class Test(Process):
    # 因为Process类本身也有__init__方法,这个子类相当于重写了这个方法,
    # 但这样就会带来一个问题,我们并没有完全的初始化一个Process类,所以就不能使用从这个类继承的一些方法和属性,
    # 最好的方法就是将继承类本身传递给Process.__init__方法,完成这些初始化操作
    def __init__(self, name, age, like):
        Process.__init__(self)
        self.name = name
        self.age = age
        self.like = like

    def run(self):
        print(f'name={self.name},age={self.age},like={self.like},进程号是:{os.getpid()}')

if __name__ == '__main__':
    t = Test('张三', 18, '跑步')
    t.start()

结果:
在这里插入图片描述

Process类常用方法

在这里插入图片描述

  • start():启动进程,并调用该子进程中的p.run()
  • run():进程启动进运行的方法,就是它去调用target指定的函数,我们自定义类的类中一定要实现该方法。
  • terminate():强制终止进程。不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用此方法需要小心:如果此进
  • 还保存了一个锁那么也将不会释放这个锁,进而导致死锁。
  • is_alive():判断进程是否是“活着”的状态。
  • join(timeout):让主线程等待某一子进程结束,才继续执行主进程。timeout是可选的超时时间。超过一个时间主进程就不等待了。
  • kill():终止当前进程,使其立即退出

多进程的问题:

  • 通过进程模块执行的函数无法获取返回值
  • 多个进程同时修改文件可能会出现错误
  • 进程数量太多可能会造成资源不足,甚至死机等情况

注:

  • os.getpid():获取当前进程id
  • os.getppid():获取父进程id

例1:使用单进程

import os
import time

def test1():
    for i in range(3):
        print(f'a={i},进程号是:{os.getpid()}')
        time.sleep(1)

def test2():
    for i in range(3):
        print(f'b={i},进程号是:{os.getpid()}')
        time.sleep(1)

if __name__ == '__main__':
    # 开始时间
    start_time = time.time()
    test1()
    test2()
    # 结束时间
    now_time = time.time()
    # 时间间隔
    time = now_time - start_time
    print(f'时间间隔:{time},进程号是:{os.getpid()}')

结果:进程号始终都是5628,说明是单进程执行的,所以最后的间隔时间是6s左右
在这里插入图片描述

例2:函数test1创建一个进程

import os
import time
import multiprocessing

def test1():
    for i in range(3):
        print(f'test1={i},进程号是:{os.getpid()}')
        time.sleep(1)

def test2():
    for i in range(3):
        print(f'test2={i},进程号是:{os.getpid()}')
        time.sleep(1)

if __name__ == '__main__':
    # 开始时间
    start_time = time.time()
    # 创建一个线程
    a = multiprocessing.Process(target=test1)
    # 开启线程
    a.start()
    test2()
    # 结束时间
    now_time = time.time()
    # 时间间隔
    time = now_time - start_time
    print(f'时间间隔:{time},进程号是:{os.getpid()}')

结果:

  • 进程16368执行了开始时间、test2函数、结束时间、最后打印print
  • 进程9327执行了test1函数
  • 这2个进程是同时执行的,所以最后的的间隔时间大概是3s
    在这里插入图片描述

例3:2个函数分别设置进程

import os
import time
import multiprocessing

def test1():
    for i in range(3):
        print(f'test1={i},进程号是:{os.getpid()}')
        time.sleep(1)

def test2():
    for i in range(3):
        print(f'test2={i},进程号是:{os.getpid()}')
        time.sleep(1)

if __name__ == '__main__':
    # 开始时间
    start_time = time.time()
    # 创建2个进程
    a = multiprocessing.Process(target=test1)
    b = multiprocessing.Process(target=test2)
    # 执行进程a和b
    for i in (a, b):
        i.start()
    # 结束时间
    now_time = time.time()
    # 时间间隔
    time = now_time - start_time
    print(f'时间间隔:{time},进程号是:{os.getpid()}')

结果:

  • 进程15960执行了开始时间和结束时间,以及最后的打印时间间隔
  • 进程9488执行了test1函数
  • 进程16616执行了test2函数
  • 这3个进程是同时执行的,所以打印的时间接近0s
    在这里插入图片描述

例4:阻塞其中一个子进程,等待它执行结束后再执行其他的

import os
import time
import multiprocessing

def test1():
    for i in range(3):
        print(f'test1={i},进程号是:{os.getpid()}')
        time.sleep(1)

def test2():
    for i in range(3):
        print(f'test2={i},进程号是:{os.getpid()}')
        time.sleep(1)

if __name__ == '__main__':
    # 开始时间
    start_time = time.time()
    # 创建进程
    a = multiprocessing.Process(target=test1)
    # 执行进程
    a.start()
    # 阻塞进程
    a.join()
    b = multiprocessing.Process(target=test2)
    b.start()
    # 结束时间
    now_time = time.time()
    # 时间间隔
    time = now_time - start_time
    print(f'时间间隔:{time},进程号是:{os.getpid()}')

结果:

  • 进程5152执行了test1函数
  • 进程4428和进程16136是在进程5152执行结束后才开始同时执行的
    在这里插入图片描述

例5:阻塞2个进程,等待他们执行结束后再执行其他的

import os
import time
import multiprocessing

def test1():
    for i in range(3):
        print(f'test1={i},进程号是:{os.getpid()}')
        time.sleep(1)

def test2():
    for i in range(3):
        print(f'test2={i},进程号是:{os.getpid()}')
        time.sleep(1)

if __name__ == '__main__':
    # 开始时间
    start_time = time.time()
    # 创建一个线程
    a = multiprocessing.Process(target=test1)
    b = multiprocessing.Process(target=test2)
    # 同时开始执行2个子进程
    for i in (a, b):
        i.start()
    # 阻塞2个进程
    for j in (a, b):
        i.join()
    # 结束时间
    now_time = time.time()
    # 时间间隔
    time = now_time - start_time
    print(f'时间间隔:{time},进程号是:{os.getpid()}')

结果:

  • 进程576和进程14596是同时执行的
  • 2个子进程执行结束后才开始执行进程10744
    在这里插入图片描述

例6:杀死一个进程

import os
import time
import multiprocessing

def test1():
    for i in range(3):
        print(f'test1={i},进程号是:{os.getpid()}')
        time.sleep(1)

def test2():
    for i in range(3):
        print(f'test2={i},进程号是:{os.getpid()}')
        time.sleep(1)

if __name__ == '__main__':
    # 开始时间
    start_time = time.time()
    # 创建一个线程
    a = multiprocessing.Process(target=test1)
    b = multiprocessing.Process(target=test2)
    # 同时开始执行2个子进程
    for i in (a, b):
        i.start()
    # 杀死进程
    a.kill()
    # 结束时间
    now_time = time.time()
    # 时间间隔
    time = now_time - start_time
    print(f'时间间隔:{time},进程号是:{os.getpid()}')

结果:

  • 执行test1的进程被杀死,没有执行
    在这里插入图片描述
  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值