python__系统 : 进程
在类unix操作系统下,可以用 os.fork() 创建一个新的进程,windows系统不可以:
import os ret = os.fork() print('ret=%d' % ret) if ret == 0: print('这是子进程:%d,继承自:%d' % (os.getpid(), os.getppid())) else: print('这是父进程:%d' % os.getpid()) >>>ret=0 这是子进程:1537,继承自:1536 ret=1537 这是父进程:1536
在执行了 os.fork() 这一句之后,会有两个进程同时向下执行, 返回的 ret 分别是 0(子进程)的 和 大于0(父进程)的 ,
getpid() 是获取当前进程的pid getppid() 是获取父进程的 pid 所以可以看出子进程 1537继承自1536.
注意父进程的结束并不会导致子进程的停止.
所以,一般,用 multiprocessing 模块来创建一个新的进程,多系统通用:
from multiprocessing import Process import time import test2 if __name__ == '__main__': p = Process(target=test2.test) p.start() while True: print('----mian----') time.sleep(1) >>>----mian---- ----test---- ----mian---- ----test----
target 里面是子进程调用对象的名称. (函数放在这个文件里面执行有bug,所以放在了 test2.py 文件里面,不加if __name__ == '__main__': 这一行也会有bug)
Process语法结构如下:
Process([group [, target [, name [, args [, kwargs]]]]])
-
target:表示这个进程实例所调用对象;
-
args:表示调用对象的位置参数元组;
-
kwargs:表示调用对象的关键字参数字典;
-
name:为当前进程实例的别名;
-
group:大多数情况下用不到;
Process类常用方法:
-
is_alive():判断进程实例是否还在执行;
-
join([timeout]):是否等待进程实例执行结束,或等待多少秒;
-
start():启动进程实例(创建子进程);
-
run():如果没有给定target参数,对这个对象调用start()方法时,就将执行对象中的run()方法;
-
terminate():不管任务是否完成,立即终止;
Process类常用属性:
-
name:当前进程实例别名,默认为Process-N,N为从1开始递增的整数;
- pid:当前进程实例的PID值;
还有一种方式创建进程,就是Process子类创建子进程, 因为 p.start() 是调用 p的run() 方法,所以需要重写run方法:
class MyProcess(Process): def run(self): while True: print('----1----') time.sleep(1) if __name__ == '__main__': p = MyProcess() p.start() while True: print('main') time.sleep(1) >>>main ----1---- main ----1----
当然,还有更加简单的方法创建进程.那就是进程池:
if __name__ == '__main__': pool = Pool(3) #最多三个进程 for i in range(10): pool.apply_async(test2.test, (i,)) #添加任务 如果换成 pool.apply() 那么会以堵塞的方式添加任务,一个进程执行完才能添加下一个进程 pool.close() #关闭进程池,不能再添加任务 pool.join() #等待进程池里的任务完成
需要注意的是,进程池并不和Process一样会等待子进程的结束,而是任务完成之后马上结束主进程,所以需要 pool.join() 等待子进程结束.