Python中多进程深入解析(4)

2.如果主进程的任务在执行到某一阶段后,需要等待子进程执行完毕后才能继续执行,就需要有一种机制能够让主进程检测子进程进程是否运行完毕,在子进程执行完毕后才继续执行,否则一直在原地阻塞,这就是join方法的作用。

from multiprocessing import Process
import time

class MyProcess(Process):
    def __init__(self,name):
        super().__init__()
        self.name = name

def run(self):
        print('%s is running.'%self.name)
        time.sleep(2)
        print('%s is done.'%self.name)

if __name__ == '__main__':  # windows系统需要在main下开启进程
    p = MyProcess('子进程')  # 实例化子进程
    p.start()  # 给操作系统发送信号,把父进程的数据拷贝给子进程作为初始数据
    p.join()  # join方法,等到子进程完成之后,才会执行主进程
    print('主进程')

# 运行结果如下:
子进程 is running.
子进程 is done.
主进程

有的人可能会问了,有了join()方法的话,程序不就变成串行了吗?在这里解释一下:

进程只要start就会在开始运行了,所以p.start()时,系统中已经有了1个并发的进程了,而我们p.join()是在等p结束,没错p只要不结束主线程就不会执行,这也是问题的关键,join是让主线程在等,而p或者以后的p1/p2/p3仍然是并发执行的,等到p.join()结束,可能p1/p2/p3早都结束了,这样的话,p1/p2/p3就忽略了检测,无需等待。

所以不管有多少个join()方法,需要等到的时候仍然是耗费时间最长的那个进程运行的时间。


terminate和is_alive方法

其中is_alive()是检测进程是否存活,而terminate方法是用来关闭进程的,当然不会立马关闭

# is_alive()检测进程是否存活
from multiprocessing import Process
import time

class MyProcess(Process):
    def __init__(self,name):
        super(MyProcess, self).__init__()
        self.name = name

def run(self):
        print('%s is running'%self.name)
        time.sleep(3)
        print('%s is done'%self.name)

if __name__ == '__main__':
    p1 = MyProcess('子进程1')
    p1.start()
    print('子进程进程是否存活:',p1.is_alive())
    p1.join()
    print('主进程')
    print('第二次检测是否存活:',p1.is_alive())
   
# 运行结果为
子进程进程是否存活: True
子进程1 is running
子进程1 is done
主进程
第二次检测是否存活: False

这是由于主进程完成了任务,所以子进程就跟着主进程一起死掉了。

# terminate杀死进程,不会立马杀死掉
from multiprocessing import Process
import time

class MyProcess(Process):
    def __init__(self,name):
        super(MyProcess, self).__init__()
        self.name = name

def run(self):
        print('%s is running'%self.name)
        time.sleep(3)
        print('%s is done'%self.name)

if __name__ == '__main__':
    p1 = MyProcess('子进程1')
    p1.start()
    p1.terminate()  # 杀死子进程1
    print('第一次检测子进程进程是否存活:',p1.is_alive())
    p1.join()
    print('主进程')
    print('第二次检测是否存活:',p1.is_alive())

运行结果为:
第一次检测子进程进程是否存活: True
主进程
第二次检测是否存活: False

在p1子进程刚刚把信号传递给操作系统之后,就利用了terminate方法杀死了子进程1,但是不是立马杀死,所以此时的p1子进程还是属于存活状态,等到打印完'主进程'之后,p1就跟随着主进程死掉了,所以此时子进程存活状态为False。


name和pid方法

其中,查看当前进程PID为os.getpid()方法,os.getppid()为查看父进程的PID方法

pid方法刚刚已经说过了,所以就不举例了

# name方法
from multiprocessing import Process
import time

def task(name):
    print('%s is running'%name)
    time.sleep(2)
    print('%s is done'%name)

if __name__ == '__main__':
    p1 = Process(target=task,args=('xiao',))
    p1.start()
    p1.join()
    print(p1.name)  # 打印子进程的进程名
    print('主进程')

# 运行结果为:
xiao is running
xiao is done
Process-1  # 子进程的进程名,默认的,可以修改
主进程

# 如果想要修改进程名,只需要在实例化的时候添加name属性就可以了,具体操作为:
    p1 = Process(target=task,args=('xiao',),name='子进程1')

守护进程

主进程设置进程,然后将该进程设置成自己的守护进程。

关于守护进程需要强调两点:

1.守护进程会跟随者主进程代码执行结束后终止

2.守护进程内无法再开启子进程,否则会抛出异常

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/942b8ff73ff4d41252705a0d573d82eb.html