在类 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() 等待子进程结束.
来源: http://www.bubuko.com/infodetail-2611671.html