Python之Process学习(二十八)
在计算机中,进程是计算机资源中分配的最小资源单位,而进程的作用主要就是做数据的隔离。而作为操作系统就
分配分配进程的资源,毕竟在一个操作系统中有很多很多的程序,每个程序都有自己独立的进程。而作为线程,只负责执
行,不负责储存共享的数据,也不负责资源分配。线程是CPU调度的最小单位,同时线程是进程的一部分。每一个进程
至少有一个线程。下面结合Process的类来学习这部分的内容。
Process类完成进程的开启,销毁,以及其他的操作。下面结合具体的案例来说明这部分的应用。
#!/usr/bin/env python # -*-coding:utf-8 -*- import os import time as t from multiprocessing import Process def func(): t.sleep(1) print('无涯课堂') if __name__ == '__main__': p=Process(target=func) #启动一个进程 p.start() print('获取父进程的PID:{0}'.format(os.getppid())) print('获取子进程的PID:{0}'.format(os.getpid()))
如上的代码执行后,见执行的结果输出:
依据输出,可以看到父进程的PID和子进程的PID,以及进程的执行后的输出内容。子进程是由父进程创建的。同时依据输出的
结果也可以看到先打印父进程和字进程的PID,后打印调用进程的程序的输出内容。这说明开启进程是一个异步的过程,并不是
一个同步的过程,异步的过程可以理解为开启一个进程并不表示这个进程真的开启,主进程必须要等待子进程结束后才可以结束。
作为主进程回收子进程的资源,如果子进程执行结束而主进程没有回收子进程的资源,就会导致子进程成一个僵尸进程。所以主
进程结束的顺序应该是:主进程的代码执行结束-->所有子进程结束-->回收子进程资源-->主进程结束。那么作为主进程又是如何知
道子进程是怎么结束的了?一般是基于文件的操作或者是具体的值来判断。再看一个案例,比如吃饭,开始吃饭,然后子进程的PID
后结束吃饭,看这个输出内容:
#!/usr/bin/env python # -*-coding:utf-8 -*- from multiprocessing import Process import time as t import os def eat(): print('开始吃饭') print(os.getpid()) print('吃饭结束') if __name__ == '__main__': p=Process(target=eat) p.start()
执行如上的代码后,它的输出内容是:
C:\Python37\python3.exe D:/git/GITHUB/FullStack/threadStudy/f2.py 开始吃饭 4672 吃饭结束
在实际的应用案例中,一般都是多个进程的并发,假设发送邮件就是一个并发的过程,因为发送邮件是给很多人,不可能
专门给一个一个发完后这样的操作,也不符合实际的生活场景。
#!/usr/bin/env python # -*-coding:utf-8 -*- from multiprocessing import Process import time as t import random def send_email(func): '''发送邮件''' t.sleep(random.random()) print('Send Mail',func) if __name__ == '__main__': lists=[] for i in range(10): p1=Process(target=send_email,args=(i,)) p1.start() lists.append(p1) for p in lists:p.join() print('报告领导,邮件发送完毕!')
继续看守护进程,守护进程是随着主进程结束而结束的,一般来说,在生产者与消费者的模型中守护进程会使用到,设置
守护进程的方法也是比较简单的,就是把进程设置为daemon=True,就是守护进程。terminate是强制结束进程,但是进程并
不是马上立刻就结束,而是会继续往下执行,不会造成堵塞。
#!/usr/bin/env python # -*-coding:utf-8 -*- from multiprocessing import Process import time as t def func(): while True: print('Hello 进程') t.sleep(0.5) if __name__ == '__main__': p=Process(target=func) #设置为守护进程 p.daemon=True p.start() print('判断当前进程是否活着:{0}'.format(p.is_alive())) t.sleep(1) p.terminate()