进程在内存中开启多个,操作系统如何区分这些进程,每个进程都有一个唯一表示
一,终端查看所有pid tasklist
二,指定具体的PID tasklist | findstr python 三,代码查看pid os 模块
### 利用os 模块 查看 pid(当前进程id) 和 ppid(父进程id) import os import time print('子进程pid:',os.getpid()) # 查看当前python程序的pid print('父进程pid:',os.getppid()) #pycharm的pid time.sleep(100)如果主进程中x的值是否改变,没有改变则说明父进程与子进程之间数据隔离
开启两个程序 一个QQ,一个微信, 开启了两个进程.如果进程之间可以通信, 那QQ的进程是不是可以任意访问微信的数据. 这样会造成诸多问题. 所以,进程间理论上是不能通信的. 但是可以借助中间代理(队列)
# -*-coding:utf-8-*- # Author:Ds from multiprocessing import Process x=1000 def task(): global x # 引用成全局变量 x=2 # 修改全局变量( 由于数据隔离,修改的数据只存在子进程中) if __name__ == '__main__': p1=Process(target=task,) p1.start() # 如果x的值没有改变,说明父进程与子进程之间数据隔离 print(f'主进程中的x的变量:{x}')只有数字能被沿用,范围:-5~256, 主进程子进程是沿用同一个.字符串等其他数据类型不延用
# -*-coding:utf-8-*- # Author:Ds from multiprocessing import Process import time x=100 def task(): print(f'子进程中:{id(x)}') if __name__ == '__main__': # 子进程与父进程之间的空间隔离., 要验证初始变量是否是一个id. print(f'主进程中:{id(x)}') p1=Process(target=task,) p1.start() time.sleep(3)join进程等待,等待主进程等待子进程结束之后再执行.不会被夯住(不会卡住)
### 并行 , 一共执行3秒. (前提是你已经创建3个子进程) #原因:1. start方法 只是告诉主进程, 开启一个子线程. # 2. join方法是等待 from multiprocessing import Process import time def task(name,sec): print(f'{name}is running') time.sleep(sec) print(f'{name} is done') if __name__ == '__main__': start_time=time.time() #记录程序开始运行时间 p1=Process(target=task,args=('alex',1)) p2=Process(target=task,args=('abc',2)) p3=Process(target=task,args=('ds',3)) # 现在内存中几乎同时创建了3个子进程 # 随机性,创建子线程时间可能不同. 操作系统调用cpu先运行谁,谁先执行. p1.start() p2.start() p3.start() ### 相当于: 现在内存中存在3个任务,同时进行,第一个任务执行1秒停顿, join方法,. 第二个任务已经执行了1秒,再执行1秒.over.第三个任务已经执行2秒停顿.再执行1秒.over. p1.join() # 通知cpu 等待子进程执行完就执行主进程 p2.join() # 通知cpu 等待子进程执行完就执行主进程 p3.join() # 通知cpu 等待子进程执行完就执行主进程 ### 以最时间长的为标准. 执行完子进程再执行父进程的打印. print(f'执行总时长:{time.time()-start_time}') ### 总结: 三次start开启了三个通道.同时进行join 只是通知cpu要等待子进程执行完毕,再执行主进程 ### for循环简化上述代码: from multiprocessing import Process import time def task(name,sec): print(f'{name}is running') time.sleep(sec) print(f'{name} is done') if __name__ == '__main__': start_time=time.time() p_l=[] # 把子线程对象,放在列表中 for e in range(1,4): e=Process(target=task,args=('alex',3)) e.start() p_l.append(e) for i in p_l: i.join() print(f'{time.time()-start_time}') ### join 串行 from multiprocessing import Process import time def task(name,sec): print(f'{name} is running') time.sleep(sec) print(f'{name} is done') if __name__ == '__main__': start_time=time.time() p1=Process(target=task,args=('alex',1)) p2=Process(target=task,args=('abc',2)) p3=Process(target=task,args=('ds',3)) p1.start() # 先创建p1 子进程并执行 p1.join() # 通知cpu 等待子进程执行完毕,再执行主进程 p2.start() # 等待p1执行完毕在开启p2进程 p2.join() p3.start() # 等待p1.p2执行完毕在开启p3进程 p3.join() # 最少6秒,还有系统调度cpu创建进程时间,往往高于6秒 print(f'执行总时长:{time.time()-start_time}') ### 总结: 一次 start 一次 join 相当于开了一个通道. 只能一次过以一辆车. join通知cpu等待子进程完成后才能继续执行主进程pid:获取子进程id
name:获取子进程name属性
terminate:杀死子进程
is_alive:查看子进程是否还活着
# -*-coding:utf-8-*- # Author:Ds from multiprocessing import Process import time def task(): print('子线程 is running') if __name__ == '__main__': p=Process(target=task,name='任务1') p.start() print(p.pid) # 获取子进程的pid print(p.name) # 获取子进程的name属性 p.terminate() # 杀死进程 :通知操作系统执行当前任务(耗时) time.sleep(1) # 由于is_alive存在主进程中.所以需要睡1秒之后再进行查看 print(p.is_alive()) print('主进程')每个进程退出时,内核释放应该进程所有的资源,但是还会保留一部分的信息,如:进程号,进程状态,运行时间.直到主进程利用这个waitepid()方法,才能够完全释放,回收子进程的资源
主进程(父进程)不能正常的使用waitepid()方法对子进程进行资源回收,这个状态是僵尸状态(Z状态).那么这部分的子进程就会成为僵尸进程
每一次子进程结束前,都会有一个僵尸状态.直到父进程调用waitepid()才会从僵尸态到消亡态
僵尸进程的资源无法被释放,长期占用.内存压力增大.当新的程序来处理时,则会因为资源不足而导致运行失败.
kill -9 pid 是杀不死僵尸进程的,他能将进程的状态从正在运行态变成僵尸态,却不能将僵尸态的进程变为消亡态
# -*-coding:utf-8-*- # Author:Ds #### 父进程不能给子进程收尸 ,子进程就是僵尸进程 from multiprocessing import Process import time import os def task(name): print(f'{name} is running') print(f'子进程开始了:{os.getpid()}') time.sleep(50) if __name__ == '__main__': for i in range(100000): p = Process(target=task,args=('怼哥',)) p.start() print(f'\033[1;35;0m 主进程:{os.getpid()}\033[0m')父进程已经挂掉了,子进程还在运行.这个子进程就是孤儿进程. 孤儿进程会被'init'进程回收
from multiprocessing import Process import time import os def task(name): for i in range(20): time.sleep(0.5) print(f'子进程开始了:{os.getpid()}') if __name__ == '__main__': p = Process(target=task,args=('怼哥',)) p.start() time.sleep(3) print(f'\033[1;35;0m 主进程:{os.getpid()}\033[0m') # 父进程 正常对退出,子进程还有自己的事情没有干完. 所以子进程成为孤儿进程守护进程本身是一个子进程,守护的主进程
结束条件:主进程代码结束了,守护进程也就结束了
### 守护进程也属于子进程,主进程代码结束前结束.因为主进程要回收子进程的资源 # 1. 主进程的代码结束,守护进程结束 # 2. 主进程要回收守护进程(子进程)的资源 # 3. 等待其他所有子进程结束 # 4. 主进程回收所有子进程资源 # -*-coding:utf-8-*- # Author:Ds from multiprocessing import Process import time import os def task(name): for i in range(20): time.sleep(0.5) print(f'子进程开始了:{os.getpid()}') def func2(): print('start:func2') time.sleep(5) print('end:func2') if __name__ == '__main__': start_time=time.time() p = Process(target=task,args=('怼哥',)) p.daemon=True # 设置为守护进程 p.start() Process(target=func2).start() print('in main') time.sleep(3) print(f'主进程开始了:{os.getpid()} ,结束时间{time.time()-start_time}') ### 一个py文件相当于开启了一个进程 ,这是一个主进程. # 主进程会等待所有的非守护进程运行完毕才结束哦 --->?为什么? 因为主进程要对所有的子进程进行资源回收 # 守护进程守护是什么? 是主进程的'代码运行完毕'. 守护进程就结束了. # 个人理解: 主进程会等待所有的非守护进程的子进程执行完毕. 连同守护进程的资源统一回收. ################################################################################################## ### 为什么要有主进程等待子进程结束之后才结束呢? # 1.因为主进程负责给子进程回收一些系统资源 ### 守护进程:本身是一个子进程,守护的主进程 # 结束条件:主进程代码结束了,守护进程也就结束了 ### 进程 # 主进程的代码结束,守护进程结束 # 主进程要回收守护进程(子进程)的资源 # 等待其他所有子进程结束 # 主进程回收所有子进程资源转载于:https://www.cnblogs.com/dengl/p/11227513.html
相关资源:JAVA上百实例源码以及开源项目