1python系统编程
1.1进程
1.1.1多任务的引入
单任务:
多任务:
说明:
·程序执行到os.fork()时,操作系统会创建一个新的进程(子进程),然后复制父进程的所有信息到子进程
·然后父进程和子进程都会从fork()函数中得到一个返回值,在子进程中这个值一定是0,而父进程中是子进程的id号。
注意:子进程永远返回 0,而父进程返回 子进程的 I D。
1.1.1多次fork问题
这时候会产生四个进程。
多进程修改全局变量
打印的结果: 哈哈1---- num=1 哈哈2---- num=1
总结:多进程中,每个进程中所有数据(包括全局变量)都各有拥有一份,互 不影响。也就是说相当于有两个num。互不干扰。
1.1.1 getpid():获得这个进程的id
解释:哪个进程运行了这个代码,就获得这个进程编号的pid
getppid():获得这个进程的父进程的id
解释:哪个进程运行了这个代码,就获得这个进程的父进程编号的pid
代码:
import os
rpid = os.fork()
if rpid<0:
print("fork调用失败。")
elif rpid ==0:
print("我是子进程(%s),我的父进程是(%s)"%(os.getpid(),os.getppid()))
else:
print("我是父进程(%s),我的子进程是(%s)"%(os.getpid(),rpid))
print("父子进程都可以执行这里的代码")
运行结果:
我是父进程(19360),我的子进程是(19361)
父子进程都可以执行这里的代码
我是子进程(19361),我的父进程是(19360)
父子进程都可以执行这里的代码。
1.1.1multiprocessing
Python是跨平台的,也提供一个跨平台的多进程。multiprocessing模块就是跨平台版本的多进程模块
multiprocessing模块提供了一个Process类来代表一个进程对象。
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值;
例子2: join()的作用
例子3: join(timeout)的作用
例子4:设置守护进程
例子5:多进程 唱歌跳舞
例子6:两个子进程.join()的运行顺序
例子7:两个子进程,一个设置成守护进程,对另一个不受影响。
1.1.1第二种实现多进程的方法:创建-Process子类
2、继承类创建的多进程的唱歌跳舞
两种方式的对比:
1、方法
2、继承类
继承类是以面向对象考虑这个事的,所以业务逻辑复杂,建议使用继承类,更好理解
1.1.1进程池Pool
apply_async非堵塞: 谁先运行完下一个接着上去。
apply堵塞: 一个运行完在运行下一个。
1.1.1进程间通信-Queue
Process之间有时需要通信,操作系统提供了很多机制来实现进程间的通信
可以使用multiprocessing模块的Queue实现多进程之间的数据传递
说明:
初始化Queue()对象时(例如:q=Queue()),若括号中没有指定最大可接收的消息数量,或数量为负值,那么就代表可接受的消息数量没有上限(直到内存的尽头);