开启子进程的两种方式、进程间内存空间隔离、进程对象的方法或属性详解
1、操作系统(推荐查看书籍:现代操作系统)
操作系统是位于计算机硬件与软件之间的控制程序
作用:
1、将硬件的复杂操作封装成简单的接口,给用户或者应用程序使用
2、将多个应用程序对硬件的竞争变的有序
2、进程
一个正在运行的程序或者说是一个程序的运行过程
3、串行、并发、并行
串行:一个任务完完整整运行完毕,才执行下一个程序
并发:多个任务看起来是同时运行的效果,单核就可以实现并发
并行:多个任务真正意义上同时运行的效果,多核才可以实现并行
4、多道技术
背景:想要在单核下实现并发(单核同一时刻只能执行一个任务)
并发实现的本质就是:切换+保存状态
多道技术:
1、空间上的复用——》多个任务共用一个内存条,但占用内存是彼此隔离的,而且是物理层面隔离
2、时间上的复用——》多个任务共用同一个CPU
切换:
1、遇到I/O操作进行切换2、一个任务占用CPU时间过长,或者有另外一个优先级更高的任务抢走cpu执行权限
一、进程与程序的区别:
进程是正在进行的一个过程,或者说是一个任务,负责执行任务的是CPU。
程序只是执行 任务背后实施的代码
注意:同一个程序执行两次,是两个进程,如打开两个QQ,一个大号,一个小号,只是进程名一样罢了。
二、并发与并行:
无论是并发还是并行,在用户使用时感觉都差不多,不管是进程还是线程,都只是任务而已,真正驱使任务干活的是cpu,而单个cpu只能同时执行一个任务。
1.并发:是伪并行,看起来是同时运行。单个cpu+多道技术就可以实现并发(并行也属于并发)
2.并行:同时运行,具有多个cpu才能实现并行效果
三、关于创建子进程:
1.相同的是:进程创建后,父进程和子进程都有各自不同的地址空间(多道技术要求物理层面实现进程之间内存的隔离),任何一个进程其在地址空间中的修改都不会影响到另外一个进程。
2.不同的是:在UNIX中,子进程的初始地址空间是父进程的一个副本。提示:子进程和父进程是可以有只读的共享内存区的。但是对于windows系统来说,从一开始父进程和子进程的地址空间是不同的。
四、进程的终止
1.正常退出(自愿,如用户点击程序上的关闭按钮或者程序执行完毕调用发起系统调用正常退出,在linux用exit,在windows中用ExitProcess)
2.出错退出(自愿,python a.py中a.py不存在)
3.严重错误(非自愿,执行非法指令,如引用不存在的内存,1/0等,可以捕捉异常,try.....except...)
4.被其他进程杀死(非自愿,如kill -9)
五、进程的层次结构
无论UNIX还是windows,只能有一个父进程,不同的区别:
1.UNIX中所有课程都是以init进程为根,组成树形结构。父、子进程共同组成一个进程组,当有信号指令发送过来后会将送达到进程组内所有成员。
2.在windows中,没有进程层次的概念,所有进程都是地位相同的,唯一类似于进程层次的暗示,是在创建进程时,父进程得到一个特别的令牌(称为句柄),该句柄可以用来控制子进程,但是父进程有权把该句柄传给其他子进程,因此没有层次之说。
六、进程的状态
两种情况下会导致一个进程在逻辑上的不能运行:
1、进程挂起是自身原因,遇到I/O阻塞,便要让出CPU为其它进程执行任务,这样就保证CPU随时保持工作状态
2、与进程无关,与操作系统有关。由于一个进程占用时间过长,或者优先级更高任务切换进入等原因,而调用其他的进程去使用CPU
进程具有有有三种状态:
七、进程并发的实现
进程并发的实现在于,硬件中断一个正在运行的进程,把此时进程运行的所有状态保存下来,为此,操作系统维护一张表格,即进程表(process table),每个进程占用一个进程表项(这些表项称为进程控制块)
该表存放了进程状态的重要信息:程序计数器、堆栈指针、内存分配状态、所有打开文件的状态、账号和高度信息,以及其他进程由运行态转为就绪态或阻塞态时,必须保存的信息,从而保证该进程在两次启动时,能够从上一次断开处继续进一步操作,而没有任何影响。
python并发编程之多进程
multiprocessing模块:用来开启子进程并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似.
multiprocessing模块的功能众多:支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。
需要再次强调的一点是:与线程不同,进程没有任何共享状态,进程修改的数据,改动仅限于该进程内。
创建进程的类:
Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进
程中的任务(尚未启动)强调:
1. 需要使用关键字的方式来指定参数
2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号
参数介绍:
1 group参数未使用,值始终为None2 target表示调用对象,即子进程要执行的任务3 args表示调用对象的位置参数元组,args=(1,2,'egon',)4 kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}5 name为子进程的名称
方法介绍:1 p.start():启动进程,并调用该子进程中的p.run() 2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法 3 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用
该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁4 p.is_alive():如果p仍然运行,返回True5 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可
选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程
属性介绍:
1 p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,
并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置2 p.name:进程的名称3 p.pid:进程的pid4 p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可)5 p.authkey:进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。这个键的用途是为涉及网络
连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功(了解即可)
Process类的使用:
注意:在windows中Process()必须放到 # if __name__ == '__main__':下
开启子进程的两种方式
方式一:
from multiprocessing import Process
import time
def task(x):print('%s is running' %x)time.sleep(3) #为了出现效果而让子进程睡3秒print('%s is done' %x)
if__name__=='__main__':#p=Process(target=task,kwargs={'x':'子进程'}) #此例子中不建议使用关键字参数p=Process(target=task,args=('子进程,')) #如果args=(),括号内只有一个参数,一定记住加逗号p.start() #只是在操作系统发送一个开启子进程的信号print('主')
结果:
主
子进程 is running
'''期间等待3秒多'''
子进程 is done方式二:
from multiprocessing import Process
import time
class Myprocess(Process):def __init__(self,x):super().__init__()self.name=xdef run(self):#固定模版,必须使用print('%s is running' %self.name)time.sleep(3)print('%s is done' %self.name)
if __name__=='__main__':p=Process('子进程1')p.start() #p.run()print('主')
结果:
主
子进程 is running
'''期间等待3秒多'''
子进程 is done
进程之间的内存空间是隔离的
from multiprocessing import Process
n=100 #在windows系统中应该把全局变量定义在if __name__ == '__main__'之上就可以了
def work():global nn=0print('子进程内: ',n)if __name__ == '__main__':p=Process(target=work)p.start()print('主进程内: ',n)
孤儿进程及僵尸进程概念:
在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程。子进程的结束和父进程的运行时
一个异步过程,即父进程永远无法预测子进程到底什么结束。当一个进程完成它的工作终止之后,它的父进程需要调用
wait()或者waitpid()系统调用取得子进程的终止进程。
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所‘收养’,并由init进程对它们完成状态收集工作。
僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。
举例:
def task(x,n):print('%s is running' % x)time.sleep(n)print('%s is done' % x)if __name__ == '__main__':# Process(target=task,kwargs={'x':'子进程'})p1 = Process(target=task, args=('子进程1',3)) # 如果args=(),括号内只有一个参数,一定记住加逗号p2 = Process(target=task, args=('子进程2',5)) # 如果args=(),括号内只有一个参数,一定记住加逗号p1.start() # 只是在操作系统发送一个开启子进程的信号p2.start() # 只是在操作系统发送一个开启子进程的信号print('主')
from multiprocessing import Process
import timex=100
def task():global xx=0print('done')
if __name__ == '__main__':p=Process(target=task)p.start()time.sleep(5) # 让父进程在原地等待,等了5s后,才执行下一行代码print(x)
进程对象的方法或属性详解
from multiprocessing import Process
import time
import osdef task():# 查看子进程号及父进程号print('自己的id:%s 父进程的id:%s ' %(os.getpid(),os.getppid()))time.sleep(200)if __name__ == '__main__':p1=Process(target=task)p1.start()# 查看父进程号及运行此代码的pycharm进程号print('主',os.getpid(),os.getppid())# 爹=》主--》儿子
了解:
from multiprocessing import Process,current_process
import timedef task():# 查看子进程名print('子进程[%s]运行。。。。' %current_process().name) time.sleep(200)if __name__ == '__main__':# 自定义进程名p1=Process(target=task,name='子进程1')p1.start()# 查看子进程名# print(p1.name)print('主')
from multiprocessing import Process,current_process
import timedef task():print('子进程[%s]运行。。。。' %current_process().name)time.sleep(2)if __name__ == '__main__':p1=Process(target=task,name='子进程1')p1.start()# is_alive:查看进程是否存活# print(p1.is_alive())# p1.join()# print(p1.is_alive())# 终止进程,terminate和start是应用程序发信号,让操作系统执行操作p1.terminate()time.sleep(1)print(p1.is_alive())print('主')
开启子进程的两种方式、进程间内存空间隔离、进程对象的方法或属性详解相关推荐
- 开启子进程的两种方式,孤儿进程与僵尸进程,守护进程,互斥锁,IPC机制,生产者与消费者模型...
开启子进程的两种方式 # # # 方式一: # from multiprocessing import Process # import time # # def task(x): # print(' ...
- 进程理论以及开启子进程的两种方式
进程理论(book:现代操作系统) 为何开启子进程需要放在main下面:因为运行到start他会向操作系统发起启动子进程的信号,然后操作系统会把整个代码块执行下,找到子进程要执行的任务, 代码运行到最 ...
- linux 僵尸进程deffunc,多进程-开启子进程的两种方式,查看进程的pid与ppid,僵尸进程与孤儿进程...
一.开启子进程的两种方式 方式一: # 方式一: from multiprocessing import Process import time def task(name): print(" ...
- 5.1.2 网络编程进阶---开启子进程的两种方式,进程之间内存空间是相互隔离的...
当主进程开启子进程后,主进程会与子进程并行执行.当主进程执行后不会立马结束进程,而是会等子进程结束才结束,好去清理僵尸子进程(给子进程收尸). 进程之间内存是相互隔离的.当创建子进程时,会把父进程的内 ...
- python 开启子进程的两种方式
进程: 是程序执行过程 启动进程,用某种方式开启子进程,帮咱们把咱们这个进程里的某一个任务并发执行以下 from multiprocessing import Process import timed ...
- 学习笔记(16):Python网络编程并发编程-开启子进程的两种方式
立即学习:https://edu.csdn.net/course/play/24458/296424?utm_source=blogtoedu #方式一:使用python内置模块multiproces ...
- 开启子进程的两种方式
方式一 from multiprocessing import Process import timedef task(name):print('%s is running' % name)time. ...
- 7 并发编程-(线程)-开启线程的两种方式
thread/英 /θred/ 美 /θrɛd/ 线程 1.threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再 ...
- Python 35 线程(1)线程理论、开启线程的两种方式
一:线程理论 1 什么是线程 进程其实一个资源单位,而进程内的线程才是cpu上的执行单位 线程其实指的就是代码的执行过程 2 为何要用线程 线程vs进程 1. 同一进程下的多个线程共享 ...
最新文章
- 关于Android学习
- graphpad的折线图x轴自定义_Graphpad Prism绘制折线图
- python标准输入输出用来干什么_python 以标准输出(sys.stdout)为例,看python的标准输入、标准错误输出...
- php 重定向数据不丢失,PHP重定向如何实现数据不丢失?
- HA集群之三:corosync+pacemaker实现httpd服务的高可用
- 关于redis集群脑裂及其解决方案
- eclipse 打包 apk 文件
- C/C++ map函数统计每个字母出现的次数
- php 获取alexa排名
- 二分类图片标签从0-1改为0-255——将图片位深度从1改为8
- XBee无线模块的通信方式和结合Arduino的具体实施过程
- 读书笔记:大型网站技术架构-核心原理与案例分析
- 【OI生涯】我学OI是为了什么?
- MAC装win10 清理临时文件
- C++:数组、链表与哈希表
- Python的学习(二十一)----Python的静态变量
- L1, L2, smooth_L1 Loss函数python实现
- APL在Web应用系列 --- 例子1: 在Web页面的javascript中 调用 apl脚本
- 生化危机2重制版 小笔记
- 【技巧】UITableView 在UITableViewStylePlain模型下,取消headerView的黏结性,不浮动