暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Python 使用【代码的方式】梳理【进程】知识点

小儿来一壶枸杞酒泡茶 2021-04-30
578

之前我们的从前几个面展开了关于进程的描述,但是很少涉及从代码的层面上进行实践探讨。以下主要是针对python中关于我们的进程一些知识点的总结和梳理。

1 进程知识点回顾:

并行和并发:

并行处理:指在同一时刻,有多条指令在多个处理器上同时执行。

  • 无论从微观还是从宏观来看,二者都是一起执行的。
  • 并行处理的主要目:节省大型和复杂问题的解决时间。

并发处理:指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果。

  • 微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。

程序和进程的区别:

进程:是系统进行资源分配的基本单位(线程是基本的调度单位)。

程序:是一些指令和数据相关组织形式的描述。

进程是程序的实体(程序的表现形式是以进程的方式来展示,程序启动后就是已进程的方式存在)。

进程拥有自己独占的虚拟地址空间(操作系统对主存一种抽象概念,每个进程只能访问自己的地址空间)。

总结:每个应用程序都有一个自己的进程,每个进程独占的虚拟地址空间,进程占据的内存空间主要由:三个部分组成:

进程= PCB(一种数据结果,对应叫做进程控制块)+ 程序段+数据段

  • 程序段:是程序代码的一些了指令集,存放要执行的代码

  • 数据段:程序运行时使用,产生的运算数据(如:全局变量,局部变量,宏定义的常量等)

  • PCB:操作系统通过PCB来管理进程,它包含的是操作系统对进程管理所需的各自信息的一个数据结构体。

进程状态切换:

引发进程切换的事件

  • 当前进程事件片到
  • 有更高优先级的进程到达
  • 当前仅主动阻塞
  • 当前进程终止

状态切换说明

  • 阻塞态----》就绪态 :不是进程自身能控制的,是处于一种被动的行为(即使它有CPU控制权,它也⽆法运⾏)。
  • 运行态----》阻塞态:是进程自身做的出一个行为属于:主动行为
  • 不能直接由 阻塞态----》运行态(因为阻塞态是进程主动请求的,而如果进程还没有运行就无法发出运行的请求)
  • 不能直接由 就绪态----》阻塞态(因为阻塞态是进程主动请求的,而如果进程还没有运行就无法发出运行的请求) 所以如果进程不处于运行态,则无法进行相关主动切换。

补充:

  • 运⾏状态 ->  就绪状态 :如果分配给它的运⾏时间⽚⽤完,操作系统会把该进程变为就绪态,接着从就绪态选择器其他另外⼀个进程运⾏;

  • 运⾏状态 ->  结束状态 :当进程已经运⾏完成或异常出错,此时进程会被操作系统作为结束状态进行处理;

补充一种进程挂起状态的说明:

  • 挂起态:主要是用来描述进程有没有占⽤实际的物理内存空间的情况。

  • 挂起态的场景 :在虚拟内存管理,(因有限的物理内存地址)通常会把当前一些部分的处于阻塞态的进程的物流内存空间---换出---放到硬盘上,等需要再次运行的时候,再从硬盘---换入---到物理内存中。所以挂起态下进程的内存数据会保存到磁盘中,以释放空间内存供其它进程进行使用。

  • 阻塞态→挂起态:当处于阻塞态的进程遇到诸如处理器空闲、资源不足等情况时而调离内存,进入挂起态。

  • 挂起态是一种主动行为(系统调配)或用户干预

    以上的情况进程状态会暂时进行切换,然后调离内存,在条件允许时可再次被调回内存。

    • 计算机内存资源不足、或CPU空闲
    • 用户主动挂起、或系统检查资源使用情况等条件下发生的时候
    • 主要情况有:

PS:与挂起态相比,阻塞态是一种被动行为,它是在等待事件或者获取不到资源而引发的等待表现。可以理解为我们的说的同步IO阻塞。

挂起态分两种:

  • 阻塞挂载态:进程在外存(硬盘)并等待某个事件的出现;(执行换出后)
  • 就绪挂起状态:进程在外存(硬盘),但只要进⼊内存,即刻⽴刻运⾏(执行换入后)

示例:

状态流转图:

补充关于多道技术的说明:

多道技术:多道技术中的其实多道指的是多个程序,多道技术主要是为高效的路由CPU,实现是为了解决多个程序竞争或者说共享同一个资源(比如cpu)的有序调度问题而提出的一个解决方式即多路复用。

多路复用上其实有可以划分为:

  • 空间复用:如内存中同时有多道程序
  • 时间复用:复用一个cpu的时间片

进程调度

多个进程之间的交替运行,OS需必须对这些进程进行调度,相关调度需要遵循一定算法。

  • 短作业(进程)优先调度算法(SJ/PF):-对短作业或短进程优先调度的算法,该算法既可用于作业调度,也可用于进程调度。

    PS:但其对长作业不利;不能保证紧迫性作业(进程)被及时处理;作业的长短只是被估算出来的。

  • 时间片轮转(Round Robin,RR)法

  • 让每个进程在就绪队列中的等待时间与享受服务的时间成比例。

PS:CPU的处理时间分成固定大小的时间片,例如,几十毫秒至几百毫秒。如果一个进程在被调度选中之后用完了系统规定的时间片,但又未完成要求的任务,则它自行释放自己所占有的CPU而排到就绪队列的末尾,等待下一次调度。同时,进程调度程序又去调度当前就绪队列中的第一个进程。

进程创建一些说明:

因为操作系统中国为了多任务执行,所以引入进程的概念。所以进程需要被创建:通常创建新的进程几种形式有:

  • 系统初始化
  • 批处理作业的初始化
  • 子进程方式创建(由已运行的主进程创建如:nginx开启多进程,linux中的os.fork,还有subprocess.Popen等)
  • 用户的交互式请求创建一个新进程(微信PC端的多开脚本)
@echo off

start "" "D:\Program Files (x86)\Tencent\WeChat\WeChat.exe"

start "" "D:\Program Files (x86)\Tencent\WeChat\WeChat.exe"

exit

无论哪种方式,新进程的创建都是其实由一个已经存在的进程执行了一个用于创建进程的【系统调用】而创建出来的。

关于创建的子进程,UNIX和windows的区分:

  • 相同的是:进程创建后,父子进程各自有各自的地址空间,彼此相互隔离,有不同的地址空间(多道技术要求物理层面实现进程之间内存的隔离),任何一个进程的在其地址空间中的修改都不会影响到另外一个进程。

  • 不同的是:

    PS:子进程和父进程是可以有只读的共享内存区的。

    • 但是对于windows系统来说,从一开始父进程与子进程的地址空间就是不同的。
    • 在UNIX中,子进程的初始地址空间是父进程的一个副本。

2 代码的方式进程分析:

2.1 使用os模块查看我们的进程PID和PPID:

import os
import time
while True:
    print("自己的进程id", os.getpid())
    print("父进程的id", os.getppid())
    time.sleep(10)


运行上面的程序会,就会分配我们的当前程序一个进程。

while True: 为让进程一直运行方便观察

此时打开任务管理器(也可以使用命令tasklist查看):

2.2 使用psutil模块查看当前进程更多明细信息:

import psutil
import os
s = psutil.Process(os.getpid())
print('进程创建时间',s.create_time())
print("进程ID:",s.pid)
print("进程父ID:",s.ppid)
print("进程名称:",s.name())
print("进程当前状态:",s.status())
print('父进程对象:',s.parent())
print('进行执行路径',s.exe())
print('调用进程的命令',s.cmdline())
print('进程工作路径',s.cwd())
print('使用进程的用户名',s.username())
print("当前进程优先级",s.nice())
try:
    print("进程打开的文件描述符的数量(仅POSIX)",s.num_fds())
except:
    print("进程打开的文件描述符的数量(仅POSIX)""不支持获取!")

# 返回进程I/O统计信息作为(read_count、write_count、read_bytes、write_bytes) namedtuple。这些是执行的读/写调用的数量和进程读取和写入的字节数。
print("进程I/O数据统计:",s.io_counters())
try:
    print("进程运行在哪个CPU上:", s.cpu_num())
except:
    print("进程运行在哪个CPU上:""不支持获取!")


try:
    print("返回此进程使用的线程数:", s.num_threads())
except:
    print("返回此进程使用的线程数:""不支持获取!")


try:
    print("当前进程的子进程:", s.children())
except:
    print("当前进程的子进程:""不支持获取!")


try:
    print("当前进程CPU利用率:", s.cpu_percent())
except:
    print("当前进程CPU利用率:""不支持获取!")


try:
    print("进程内存信息:", s.memory_info())
except:
    print("进程内存信息:""不支持获取!")

try:
    print("进程内存占比:", s.memory_persent())
except:
    print("进程内存占比:""不支持获取!")

try:
    print("进程打开的文件:", s.open_files())
except:
    print("进程打开的文件:""不支持获取!")

try:
    print("进程打开的套接字连接:", s.connections())
except:
    print("进程打开的套接字连接:""不支持获取!")
    
print("====》"*10)
print("====》"*10)

输出:

进程创建时间 1619766753.4062777
进程ID:34276
进程父ID:xxxxx
进程名称:python.exe
进程当前状态:running
父进程对象:xxxxxxx
进行执行路径 xxxxxx
调用进程的命令 xxxxxx
进程工作路径 D:\code\python\local_python\5GMsgFlask\进程示例2
使用进程的用户名 DESKTOP-16CKEN1\mayn
当前进程优先级 Priority.NORMAL_PRIORITY_CLASS
进程打开的文件描述符的数量(仅POSIX) 不支持获取!
进程I/O数据统计:pio(read_count=151, write_count=48, read_bytes=876738, write_bytes=842, other_count=6286, other_bytes=217930)
进程运行在哪个CPU上: 不支持获取!
返回此进程使用的线程数:4
当前进程的子进程: []
当前进程CPU利用率: 0.0
进程内存信息:xxxxxxxxxxxx
进程内存占比: 不支持获取!
进程打开的文件:xxxxxxx
进程打开的套接字连接: []
====》====》====》====》====》====》====》====》====》====》
====》====》====》====》====》====》====》====》====》====》

2.3 使用multiprocessing模块进行进程的开启

multiprocessing模块可以让程序员在给定的机器上充分的利用CPU。在multiprocessing中,通过创建Process对象生成进程,然后调用它的start()方法。

注意事项项目:

官网中有一个在Window中关于进程创建的说明:

Since Windows has no fork, the multiprocessing module starts a new Python process and imports the calling module. 
If Process() gets called upon import, then this sets off an infinite succession of new processes (or until your machine runs out of resources). 
This is the reason for hiding calls to Process() inside

if __name__ == "__main__"
since statements inside this if-statement will not get called upon import.
由于Windows没有fork,多处理模块启动一个新的Python进程并导入调用模块。 
如果在导入时调用Process(),那么这将启动无限继承的新进程(或直到机器耗尽资源)。 
这是隐藏对Process()内部调用的原,使用if __name__ == “__main __”,这个if语句中的语句将不会在导入时被调用。

所以注意:在windows中建议Process()必须放到# if name == 'main':下面(测试验证好像不放也是可以)

创建进程示例:

#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   文件名称 :     test3
   文件功能描述 :   功能描述
   创建人 :       小钟同学
   创建时间 :          2021/4/30
-------------------------------------------------
   修改描述-2021/4/30:         
-------------------------------------------------
"
""
import os
print("程序开始执行--------》")
print("外层的:os.getppid()",os.getpid())
print("外层的:os.getppid()",os.getppid())
from multiprocessing import Process

def func(name):
    print('你好', name)
    print("子进程内层的自己的进程ID:os.getpid()", os.getpid())
    print("子进程内层的父进程ID:os.getppid()", os.getppid())


if __name__ == "__main__":
    print("内层的:os.getppid()", os.getpid())
    print("内层的:os.getppid()", os.getppid())
    p = Process(target=func,args=('沙和尚',))
    p.start()
    print("等待进程执行完毕!")
    p.join()  # 等待进程执行完毕
    #join 主进程只有在各个子进程执行完毕之后,才会向下执行.
    print("执行完成!")

输出结果:

程序开始执行--------》
外层的:os.getppid() 42812
外层的:os.getppid() 27908
内层的:os.getppid() 42812
内层的:os.getppid() 27908
等待进程执行完毕!
程序开始执行--------》
外层的:os.getppid() 26880
外层的:os.getppid() 44492
你好 沙和尚
子进程内层的自己的进程ID:os.getpid() 26880
子进程内层的父进程ID:os.getppid() 44492
执行完成!

程序开始执行--------》执行两次主要原因是:

windows在启动子进程的时候会将主进程文件倒入到子进程中。导入模块就相当于执行这个模块中的代码,所以第一个print会在主进程中执行一次,又在被导入的过程中在子进程中又执行了一次。

代码示例几个方法的说明:

  • p.start():进程准备就绪,可以准备开始执行,也可以理解为向操作系统发起一个进程调度的申请(或理解我们处于就绪态的进程,等待CPU分配时间片执行)
    • 注意点:p.start() 里面包含了p.run() 的调用(类似自定线程的run方法)
  • p.join():主进程需要等待我们的p进程执行完毕才可以执行,起到阻塞作用。
    • 注意点:1:是主进程进行等待阻态 2:子线程在后台中当前是处于运行态 3:p.join只能join住start开启的进程,而不能join住run开启的进程

进程属性和方法:

2.4 主进程和进程退出的无序性:

通常一般情况下,子进程都是由父进程来创建,而子进程和父进程什么时候执行结束是无法预知,所以他们的退出是无序的,两者之间都不知道谁先退出。除非你特别指定(如上面的示例加入:p.join(),后不然你自己有可能我们的主进程结束了,但是子进程还会继续运行)

import os
print("程序开始执行--------》")
from multiprocessing import Process

class MyPao(Process):

    def __init__(self,name):
        super().__init__()  # 必须继承父类的一些属性
        self.name = name

    # 必须得实现一个run方法
    def run(self):
        print('你好', self.name)
        print("子进程内层的自己的进程ID:os.getpid()", os.getpid())
        print("子进程内层的父进程ID:os.getppid()", os.getppid())
        # 守护进程内无法再开启子进程,否则抛出异常

if __name__ == "__main__":
    p= MyPao(name="沙和尚")
    # 设置的方法:在p.start之前将p.daemon = True,默认情况下daemon属性的数值为False.
    p.start()
    print("等待进程执行完毕!")
    # p.join()  # 注释了之后,主进程可能会先退出,不等待子进程执行完毕
    print("执行完成!")


PS:# p.join()  # 注释了之后,主进程可能会先退出,不等待子进程执行完毕

使用面向对象的的方式创建进程:

#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   文件名称 :     test3
   文件功能描述 :   功能描述
   创建人 :       小钟同学
   创建时间 :          2021/4/30
-------------------------------------------------
   修改描述-2021/4/30:         
-------------------------------------------------
"
""
import os
print("程序开始执行--------》")
from multiprocessing import Process

class MyPao(Process):

    def __init__(self,name):
        super().__init__()  # 必须继承父类的一些属性
        self.name = name

    # 必须得实现一个run方法
    def run(self):
        print('你好', self.name)
        print("子进程内层的自己的进程ID:os.getpid()", os.getpid())
        print("子进程内层的父进程ID:os.getppid()", os.getppid())
        # 守护进程内无法再开启子进程,否则抛出异常

if __name__ == "__main__":
    p= MyPao(name="沙和尚")
    # 设置的方法:在p.start之前将p.daemon = True,默认情况下daemon属性的数值为False.
    p.start()
    print("等待进程执行完毕!")
    p.join()  # 等待进程执行完毕
    print("执行完成!")

2.5 守护进程

守护进程的概念:

  • 进程分为:
    • 前台运行的进程
    • 后台运行的进程,
    • 其中守护进程属于后台运行的进程,是运行在后台中一种非常特殊进程。
    • 它可以独立于控制终端并且周期性 地执行某种任务或等待处理某些发生的事件。

特点:

  • 守护进程会在主进程代码执行结束后就终止。
  • 守护进程内无法再开启子进程(不能怀孕),否则会抛出异常。

守护进程的效果:把相应的子进程设置为守护进程,主进程运行完毕之后,相关的守护进程也会随后结束,被回收!

守护进程设置的方法:

设置的方法:在p.start之前将p.daemon = True,默认情况下daemon为False.

#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   文件名称 :     test3
   文件功能描述 :   功能描述
   创建人 :       小钟同学
   创建时间 :          2021/4/30
-------------------------------------------------
   修改描述-2021/4/30:         
-------------------------------------------------
"
""
import os
print("程序开始执行--------》")
# print("外层的:os.getppid()",os.getpid())
# print("外层的:os.getppid()",os.getppid())
from multiprocessing import Process
import time

def func(name):
    print('你好', name)
    print("子进程内层的自己的进程ID:os.getpid()", os.getpid())
    print("子进程内层的父进程ID:os.getppid()", os.getppid())
    # 守护进程内无法再开启子进程,否则抛出异常

    print("子进程内部可以在创建子进程(不能怀孕!)")
    # p = Process(target=time.sleep, args=(3,))
    # p.start()

if __name__ == "__main__":

    p = Process(target=func,args=('沙和尚',))
    # 设置的方法:在p.start之前将p.daemon = True,默认情况下daemon属性的数值为False.
    p.daemon=True
    p.start()
    print("等待进程执行完毕!")
    p.join()  # 等待进程执行完毕
    print("执行完成!")


注意事项:因为设置我们的子进程为守护进程, p.daemon=True所以它里面不可以在创建新的子进程。

无序状态下的一种子守护进程示例:

如果主进程不等子进程处理完成的情况,则我们的子进程会随着主进程消亡而消亡!但是子进程的结束和父进程的运行是一个异步过程。如下:

from multiprocessing import Process
import os, time, random


def task():

    print("子进程内层的自己的进程ID:os.getpid()", os.getpid())
    print("子进程内层的父进程ID:os.getppid()", os.getppid())
    time.sleep(2)
    print("子进程内层的自己的进程ID:os.getpid()---完毕", os.getpid())
    print("子进程内层的父进程ID:os.getppid())---完毕", os.getppid())
    print('子进程执行完毕了!')


if __name__ == '__main__':
    p = Process(target=task)
    p.daemon = True  # 这只为守护进程
    # 执行任务,开会创建子进程,子进程创建需开辟内存空间,需耗费时间,所以主进程,因为不需要等待子进程,会先执行完毕!
    # 因为守护进程机制,那么守护子进程p也随主进程就退出而退出!
    p.start()
    # p.join()
    print('主进程执行完毕了!')

输出结果为:

主进程执行完毕了!

如果加上需要等待子进程执行完毕恢复:p.join(),则输出的结果为:

子进程内层的自己的进程ID:os.getpid() 30940
子进程内层的父进程ID:os.getppid() 42436
子进程内层的自己的进程ID:os.getpid()---完毕 30940
子进程内层的父进程ID:os.getppid())---完毕 42436
子进程执行完毕了!
主进程执行完毕了!

2.6 守护和非守护进程的同时存在

import os
print("程序开始执行--------》")
from multiprocessing import Process

class MyPao(Process):

    def __init__(self,name):
        super().__init__()  # 必须继承父类的一些属性
        self.name = name

    # 必须得实现一个run方法
    def run(self):
        print('你好''恭喜你脱离苦海!',self.name)
        print("子进程内层的自己的进程ID:os.getpid()", os.getpid())
        print("子进程内层的父进程ID:os.getppid()", os.getppid())
        # 守护进程内无法再开启子进程,否则抛出异常

if __name__ == "__main__":
    p= MyPao(name="沙和尚--守护进程(随着唐大爷的生死与共!)")
    # 设置的方法:在p.start之前将p.daemon = True,默认情况下daemon属性的数值为False.
    p.daemon=True
    p.start()
    p= MyPao(name="孙悟空--非守护进程(我不受主进程唐大爷的掌控!)")
    # 设置的方法:在p.start之前将p.daemon = True,默认情况下daemon属性的数值为False.
    p.start()
    print("执行完成!")

输出结果为:

程序开始执行--------》
执行完成!
程序开始执行--------》
你好 恭喜你脱离苦海! 孙悟空--非守护进程(我不受主进程唐大爷的掌控!)
子进程内层的自己的进程ID:os.getpid() 38480
子进程内层的父进程ID:os.getppid() 44052

说明:上面的示例总我们的 沙和尚是守护进程,受制于主进程的生死契约!孙大爷比较厉害,它不是守护进程!所以可以脱离主进程之后,继续执行~!

PS:需要注意点强调的是:主进程运行完毕不等于终止运行!对于主进程来说,运行完毕指的是主线程所在的进程内所有【非守护的进程】全部运行完毕后,主线程才算运行完毕!

这么这么理解:

唐大爷因为离不开孙大爷,比较孙大爷是一个非守护进程(孙大爷太牛逼的无法无天,不受制于主进程,只能忍一忍!),所以需要孙大爷执行干完自己的想干的事情之后,我们的唐大爷才算真正的完成运行完毕!而沙和尚吧,没必要等他的任务的执行,太磨磨唧唧的沙大爷(它是守护进程,受制于主进程)!不想等他干完他的事,不会等他!干完干不完都不能等!

PS:主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。

2.7 僵尸进程和孤儿进程

  • 孤儿进程: 当父进程已经结束,而它的一个或多个子进程还在运行,此时子进程就称为孤儿进程,孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。(非守护进行实例的一种)

  • 僵尸进程:子进程先于父进程完成了任务进行退出,父进程又没有处理子进程的退出状态(父进程并没有调用wait或waitpid获取子进程的状态信息),此时子进程已退出,此时子进程的进程描述符一绕会存留PCB在内存中,大量这样的子进程(僵尸进程)会浪费系统的内存资源)

PS:unix中僵尸进程的含义:凡是父进程没有调用wait函数获得子进程终止状态的,对应的这些子进程在终止之后都是僵尸进程,在这个概念中关键一点就是父进程是否调用了wait函数

  • linux中 可以调用waitpid来是彻底清除子进程的残留信息

  • python中听说是已经封装了处理僵尸进程的操作 ,无需关心(具体不知道在哪里进程回收了)。

僵尸进程通常的处理方式有:

1.os.wait()阻塞等待回收子进程 缺点:父进程会阻塞,影响运行效率

import os
pid,status = os.wait()

2: childpid, status = os.waitpid(-1, os.WNOHANG)

-1 表示任意子进程

os.WNOHANG 表示如果没有需要wait的子进程,则waitpid方法立即返回

3:父进程忽略子进程退出信号,直接让系统来处理子进程退出

import os
import signal

#父进程忽略子进程退出信号,让操作系统来处理,父进程不会阻塞
signal.signal(signal.SIGCHLD,signal.SIG_IGN)


2.8 强制终止进程( p.terminate())

PS:强制终止进程,不会进行任何清理操作,如果p有创建了子进程,该子进程就成了僵尸进程。

#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   文件名称 :     test3
   文件功能描述 :   功能描述
   创建人 :       小钟同学
   创建时间 :          2021/4/30
-------------------------------------------------
   修改描述-2021/4/30:         
-------------------------------------------------
"
""
import os
print("程序开始执行--------》")
from multiprocessing import Process

class MyPao(Process):

    def __init__(self,name):
        super().__init__()  # 必须继承父类的一些属性
        self.name = name

    # 必须得实现一个run方法
    def run(self):
        print('你好', self.name)
        print("子进程内层的自己的进程ID:os.getpid()", os.getpid())
        print("子进程内层的父进程ID:os.getppid()", os.getppid())
        # 守护进程内无法再开启子进程,否则抛出异常
        self.zijinchengh =MyPao22(name="沙和尚-的孩子")
        self.zijinchengh.start()

class MyPao22(Process):

    def __init__(self, name):
        super().__init__()  # 必须继承父类的一些属性
        self.name = name

    # 必须得实现一个run方法
    def run(self):
        print('你好', self.name)
        print("子进程内层的自己的进程ID:os.getpid()", os.getpid())
        print("子进程内层的父进程ID:os.getppid()", os.getppid())
        # 守护进程内无法再开启子进程,否则抛出异常
        # print('ppobj',self.ppobj)
        # self.ppobj.terminate() # 还没执行完毕的数,沙大爷先强制结束了!!!

        import time
        time.sleep(5)
        print('-'*30, self.name)
        print('你好--完毕!', self.name)

if __name__ == "__main__":
    p= MyPao(name="沙和尚")
    # 设置的方法:在p.start之前将p.daemon = True,默认情况下daemon属性的数值为False.
    p.start()
    # 这里执行强制终止进程
    p.terminate()
    # p.terminate()
    # p.join()

    # 设置的方法:在p.start之前将p.daemon = True,默认情况下daemon属性的数值为False.


    print("等待进程执行完毕!")

    print("执行完成!")

强制结束是查看进程的状态:

#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   文件名称 :     test3
   文件功能描述 :   功能描述
   创建人 :       小钟同学
   创建时间 :          2021/4/30
-------------------------------------------------
   修改描述-2021/4/30:         
-------------------------------------------------
"
""
import os
print("程序开始执行--------》")
from multiprocessing import Process

class MyPao(Process):

    def __init__(self,name):
        super().__init__()  # 必须继承父类的一些属性
        self.name = name

    # 必须得实现一个run方法
    def run(self):
        print('你好', self.name)
        print("子进程内层的自己的进程ID:os.getpid()", os.getpid())
        print("子进程内层的父进程ID:os.getppid()", os.getppid())
        # 守护进程内无法再开启子进程,否则抛出异常
        self.zijinchengh =MyPao22(name="沙和尚-的孩子")
        self.zijinchengh.start()


class MyPao22(Process):

    def __init__(self, name):
        super().__init__()  # 必须继承父类的一些属性
        self.name = name

    # 必须得实现一个run方法
    def run(self):
        print('你好', self.name)
        print("子进程内层的自己的进程ID:os.getpid()", os.getpid())
        print("子进程内层的父进程ID:os.getppid()", os.getppid())
        # 守护进程内无法再开启子进程,否则抛出异常
        # print('ppobj',self.ppobj)
        # self.ppobj.terminate() # 还没执行完毕的数,沙大爷先强制结束了!!!

        import time
        time.sleep(5)
        print('-'*30, self.name)
        print('你好--完毕!', self.name)

if __name__ == "__main__":
    p = MyPao22('沙和尚')
    print("开始")
    p.start()
    print("当前进程的状态:",p.is_alive())
    p.terminate()
    p.join()
    # time.sleep(2)
    print("结束")
    print("强制结束后进程的状态:", p.is_alive())


输出结果:

程序开始执行--------》
开始
当前进程的状态:True
结束
强制结束后进程的状态:False

参考资料:

https://blog.csdn.net/a2011480169/article/details/75193884?utm_source=app&app_version=4.6.1

深入理解Python中的进程 :https://blog.csdn.net/a2011480169/article/details/75193884?utm_source=app&app_version=4.6.1

个人其他博客地址

简书:https://www.jianshu.com/u/d6960089b087

掘金:https://juejin.cn/user/2963939079225608

小钟同学 | 文 【原创】| QQ:308711822

  • 1:本文相关描述主要是个人的认知和见解,如有不当之处,还望各位大佬指正。
  • 2:关于文章内容,有部分内容参考自互联网,结合自己的认识梳理二次而成!如有链接会声明标注;如没有及时标注备注的链接的,如有侵权请联系,我会立即删除处理哟。


文章转载自小儿来一壶枸杞酒泡茶,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论