多进程

获取进程及主进程的pid

什么是pid

进程在内存中开启多个,操作系统区分进程的方式就是通过每个进程都有的一个唯一的标识 — pid来区分

查看pid的方式

在终端查看当前所有进程的pid

在cmd窗口中输入tasklist

在终端查看正在执行的制定名字的进程的pid

在cmd窗口中输入tasklist|findstr + 进程名字

通过代码层面查看pid

os.getpid()  查看子进程

os.getppid()   查看父进程

验证进程间的空间隔离

from multiprocessing import Process
import time
x = 1000

def task():
    global x
    x = 2

if __name__ == '__main__':
    p = Process(target=task)
    p.start()
    time.sleep(3)
    print(x)         
验证进程之间的空间隔离

join方法

join:等待,主进程等待子进程结束之后再执行

from multiprocessing import Process
import time

def task(name):
    time.sleep(1)
    print(f'{name} is running')

if __name__ == '__main__':
    p = Process(target=task,args=('alex',))
    p.start()
    p.join()  # 告知主进程,p进程结束之后,主进程再运行
    print('主进程执行')
开启多个子进程去验证:


from multiprocessing import Process
import time

def task(name):
    time.sleep(1)
    print(f'{name} is running')

if __name__ == '__main__':
    p1 = Process(target=task, args=('alex',))
    p2 = Process(target=task, args=('barry',))
    p3 = Process(target=task, args=('wusir',))
    p1.start()
    p2.start()
    p3.start()
    # p1, p2, p3 三个子进程运行的先后顺序不定
    # start只是通知一下操作系统,三个start几乎同一时刻发给操作系统
    # 操作系统调用cpu先运行谁,谁先执行
    print('主进程执行')


from multiprocessing import Process
import time

def task(name,second):
    time.sleep(second)
    print(f'{name} is running')

if __name__ == '__main__':
    p1 = Process(target=task, args=('alex', 1))
    p2 = Process(target=task, args=('barry', 2))
    p3 = Process(target=task, args=('wusir', 3))
    start_time = time.time()
    p1.start()
    p2.start()
    p3.start()
    p1.join() # 视下面代码为主进程,此种写法为并发
    p2.join()
    p3.join()
    print(f'主进程:{time.time() - start_time}之后,执行')


from multiprocessing import Process
import time

def task(name,second):
    print(f'{name} is running')
    time.sleep(second)
    print(f'{name} is done')

if __name__ == '__main__':
    p1 = Process(target=task, args=('alex', 1))
    p2 = Process(target=task, args=('barry', 2))
    p3 = Process(target=task, args=('wusir', 3))
    start_time = time.time()
    p1.start()
    p1.join()  #视下面代码为主进程,此种写法为串行
    p2.start()
    p2.join()
    p3.start()
    p3.join()
    print(f'主进程:{time.time() - start_time}之后,执行')
join方法

进程对象的其他属性

from multiprocessing import Process
import time


def task(name):

    print(f'{name} is running')
    time.sleep(3)
    print(f'{name} is done')


if __name__ == '__main__':

    p = Process(target=task,args=('怼哥',) ,name='任务1')  # name给进程对象设置name属性
    p.start()
    print(p.pid)  # 获取进程pid号
    print(p.name)
    time.sleep(1)
    p.terminate() # 终止(结束)子进程
    # terminate 与 start一样的工作原理: 都是通知操作系统终止或者开启一个子进程,内存中终止或者开启(耗费时间)
    time.sleep(1)
    print(p.is_alive())  # 判断子进程是否存活
    # 只是查看内存中p子进程是否运行.
    print('===主进程')
进程对象的其他属性

僵尸进程和孤儿进程

这是在Linux环境下才强调的两个概念,Windows环境下没有这两个概念

from multiprocessing import Process
import time
import os

def task(name):

    print(f'{name} is running')
    print(f'子进程开始了:{os.getpid()}')
    time.sleep(50)


if __name__ == '__main__':
    for i in range(100000):
        p = Process(target=task,args=('alex',))
        p.start()
    print(f'主进程开始了:{os.getpid()}')

僵尸进程

僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。

僵尸进程的内存中只包括主进程的pid,子进程的开始时间,结束时间,至于主进程的代码以及文件,数据库等全部消失。可以利用waitpid()方法对僵尸进程进行“收尸”

僵尸进程是有害的。僵尸进程如果无限的开启子进程,子进程就会越来越多,占用内存

孤儿进程

如果一个主进程退出,而它的一或多个子进程还在运行,那么那些子进程将成为孤儿进程

孤儿进程是无害的,一段时间后,init会对孤儿进程进行回收

守护进程

运行在后台并且只在需要时才唤醒的进程称为守护进程(电子邮件,web网页,新闻,打印等)

主进程创建守护进程

守护进程会在主进程代码执行结束后就终止

守护进程内不能再开启子进程,否则就会抛出异常:AssertionError: daemonic processes are not allowed to have children

注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止

#主进程代码运行完毕,守护进程就会结束
from multiprocessing import Process
from threading import Thread
import time
def foo():
    print(123)
    time.sleep(1)
    print("end123")

def bar():
    print(456)
    time.sleep(3)
    print("end456")


p1=Process(target=foo)
p2=Process(target=bar)

p1.daemon=True   #一定要在p.start()前设置,设置p为守护进程,禁止p创建子进程,并且父进程代码执行结束,p即终止运行 
p1.start()
p2.start()
print("main-------") #打印该行则主进程代码结束,则守护进程p1应该被终止,可能会有p1任务执行的打印信息123,因为主进程打印main----时,p1也执行了,但是随即被终止
守护进程示例代码
原文地址:https://www.cnblogs.com/biulo/p/11228214.html