进程比较基础的内容

Posted xiongchao0823

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程比较基础的内容相关的知识,希望对你有一定的参考价值。

1.创建多进程的两种方式

1.1 方式一(函数)

# 方式一
from multiprocessing import Process
import time

def test(name):
    print(f"name的子进程开始...")
    time.sleep(3)
    print("子进程结束...")
if __name__ == '__main__':
    p = Process(target=test,args=("xc",)) # 要用元组哦
    p.start()
    # time.sleep(3)
    print("主进程")

1.2 方式二(类)

# 方式二
from multiprocessing import Process
import time

class My(Process):
    def __init__(self,name):
        super().__init__()
        self.name = name
    def run(self):
        print(f"self.name的子进程开始...")
        time.sleep(3)
        print("子进程结束...")
if __name__ == '__main__':
    p = My('xc')
    p.start()
    print("xc的主进程")

2.孤儿进程和僵尸进程

  • 孤儿进程:其实就是主继承执行完了,子进程还没执行完,因为会变成僵尸进程,以及占用pid号,所以就会被init方法回收
  • 僵尸进程:其实就是子进程运行完了之后,他不是真正的运行完,而是会保留一些信息,其中pid是最主要的信息,僵尸进程,会在主程序执行完了之后被自动回收

3.pid,一个进程的身份证

from multiprocessing import Process
import time
import os

class My(Process):
    def __init__(self,name):
        super().__init__()
        self.name = name
    def run(self):
        print(f"self.name的子进程开始...")
        print(self.pid)
        print(os.getpid())
        print(os.getppid())
        time.sleep(3)
        print("子进程结束...")
if __name__ == '__main__':
    p = My('xc')
    print(os.getpid())
    p.start()
    print("xc的主进程")

"""
打印结果:
    11200
    xc的主进程
    xc的子进程开始...
    6664
    6664
    11200
    子进程结束...
"""

  • 通过以上数据我们了解了使用os模块的getpid和getppid方法获取进程的pid序号,其中getpid是获取当前进程的pid,而ppid是获取父进程的pid
  • 当然查看pid的方法不止这一个

4.Process的join方法

  • 等待子进程运行完,在执行主进程的代码,阻塞主程序的运行
from multiprocessing import Process
import time
def foo():
    print("程序开始...")
    time.sleep(3)
    print("程序结束...")

if __name__ == '__main__':
    p = Process(target=foo)
    p1 = Process(target=foo)
    p2 = Process(target=foo)
    start = time.time()
    p.start()
    p1.start()
    p2.start()
    p.join()     # 会阻塞主程序的运行
    p1.join()
    p2.join()
    end = time.time()
    print("主程序结束...")
    print(start-end)
# 打印结果:
    # 程序开始...
    # 程序结束...
    # 程序开始...
    # 程序开始...
    # 程序结束...
    # 程序结束...
    # 主程序结束...
    # -3.150564193725586
# 如果表示形式为以上的AAABBB形式,那么所需的时间为3s以上,说明这种写法是主程序等待所有都在运行的子程序执行完

###################################################################################################

from multiprocessing import Process
import time
def foo():
    print("程序开始...")
    time.sleep(3)
    print("程序结束...")

if __name__ == '__main__':
    p = Process(target=foo)
    p1 = Process(target=foo)
    p2 = Process(target=foo)
    start = time.time()
    p.start()
    p.join()  # 会阻塞主程序的运行
    p1.start()
    p1.join()
    p2.start()
    p2.join()
    print("主程序结束...")
    end = time.time()
    print(start-end)
# 打印结果:
    # 程序开始...
    # 程序结束...
    # 程序开始...
    # 程序结束...
    # 程序开始...
    # 程序结束...
    # 主程序结束...
    # -9.349010705947876
# 根据上面的内容来看,如果按照ABABAB执行,就会出现子程序等其他子程序执行完再执行,就会叠加时间,就是一个串行的进程了

5.Process的name和is_alive方法

  • name:查看子进程的名字(类似于这样的名字,Process-1)
  • is_alive:返回值为布尔类型,判断子进程是否结束,需要一定的结束时间,所以使用time模块等一会儿,或者使用join方法等待结束,如果还没结束就返回True,结束了就返回False
from multiprocessing import Process
import time

def foo():
    print("进程开始...")
    time.sleep(3)
    print("进程结束...")

if __name__ == '__main__':
    p = Process(target=foo)
    # print(p.is_alive())
    p.start()
    print(p.name)
    print(p.is_alive())
    time.sleep(5)
    print("主程序结束...")
    print(p.is_alive())

# 自己试验下,情况就是name这个属性对应着创建线程的一个代号,它是往下迭代的例如:Process-1,Process-2这样迭代

# 关于is_alive则是表示子程序有没有结束,主要是看子程序有没有运行完,可以使用time模块测试


6.Process的terminal

  • 强制结束子进程(类似于start,是给操作系统信号,并不是直接结束)
from multiprocessing import Process
import time

def foo():
    print("进程开始...")
    time.sleep(3)
    print("进程结束...")

if __name__ == '__main__':
    p = Process(target=foo)
    p.start()
    print(p.is_alive())
    p.terminate()  # 强制结束子进程
    p.join() # 我们必须在这里使用join,等待进程结束,那就有人问了,你等他结束了is_alive肯定是Flase呀,但是我们的注意点是子程序没有打印数据
    print(p.is_alive())
    print("主进程结束...")

# 对于Process中的terminate的使用也和start一样,他只是去给操作系统发送了关闭子进程的信号,并不是直接结束

7.守护进程

  • 忠心耿耿的进程,通过 对象名.daemon = True 的方法定义一个守护进程.
from multiprocessing import Process
import time
"""
守护进程
守护 --> 伴随
本质上也是一个子进程
主进程的代码执行完毕守护进程直接结束,但是此时主进程可能没有结束
"""
def foo():
    print("守护进程开始...")
    time.sleep(3)
    print("守护进程结束...")

if __name__ == '__main__':
    p = Process(target=foo)
    p.daemon = True # 这个就是把创建的子进程定义为守护进程,默认值应该是Flase
    p.start()
    # p.join()
    time.sleep(2)
    print("主进程结束...") # 也就是说主进程结束了,子进程就自动释放了,就是不会运行了

# 总结就是daemon这个方法把创建的子进程定义为守护进程,所谓的守护进程就是:主进程结束了,子进程也就是守护进程结束了
# 如果主进程没结束,子进程也就是守护进程便会像普通进程一样从有到无,从出现到离开
# 普通的子进程是不会管主进程的死活的,大不了变成孤儿进程继续运行,反正会有init方法回收

以上是关于进程比较基础的内容的主要内容,如果未能解决你的问题,请参考以下文章

python基础(21)-线程通信

进程的基础内容

实验六 进程基础

进程基础知识

实验六 进程基础

实验六 进程基础