Python进阶----进程间数据隔离, join阻塞等待, 进程属性, 僵尸进程和孤儿进程, 守护进程
Python进阶----进程间数据隔离, join阻塞等待, 进程属性, 僵尸进程和孤儿进程, 守护进程
一丶获取进程以及父进程的pid
含义:
进程在内存中开启多个,操作系统如何区分这些进程,每个进程都有一个唯一表示
方法三种方法:
一,终端查看所有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方法
含义:
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('主进程')
五丶僵尸进程与孤儿进程(存在Linux系统中)
进程了解:
每个进程退出时,内核释放应该进程所有的资源,但是还会保留一部分的信息,如:进程号,进程状态,运行时间.直到主进程利用这个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.因为主进程负责给子进程回收一些系统资源
### 守护进程:本身是一个子进程,守护的主进程
# 结束条件:主进程代码结束了,守护进程也就结束了
### 进程
# 主进程的代码结束,守护进程结束
# 主进程要回收守护进程(子进程)的资源
# 等待其他所有子进程结束
# 主进程回收所有子进程资源
Python进阶----进程间数据隔离, join阻塞等待, 进程属性, 僵尸进程和孤儿进程, 守护进程的更多相关文章
- 子进程回收资源两种方式,僵尸进程与孤儿进程,守护进程,进程间数据隔离,进程互斥锁,队列,IPC机制,线程,守护线程,线程池,回调函数add_done_callback,TCP服务端实现并发
子进程回收资源两种方式 - 1) join让主进程等待子进程结束,并回收子进程资源,主进程再结束并回收资源. - 2) 主进程 “正常结束” ,子进程与主进程一并被回收资源. from multipr ...
- Python 进程间数据交互
进程间通信:进程之间必须需要中间件. 不同进程间内存是不共享的,要想实现两个进程间的数据交换 Queues:实现传输两个进程的数据 线程queue,访问数据只能在一个进程内进行线程与线程之间的 ...
- 【python】-- 多进程的基本语法 、进程间数据交互与共享、进程锁和进程池的使用
多进程 进程之间是相互独立的,python是启动进程的时候,是启动的是原生进程.进程是没有GIL锁的,而且不存在锁的概念,进程之间的数据式不能共享的,而线程是可以的. 1.进程的定义 用mulipro ...
- Python多进程-进程间数据的共享
不同的进程不能同时修改一份数据,但是不同的进程能对一份数据进行修改 可通过Manager来实现进程间的数据共享 # -*- coding:utf-8 -*- __author__ = "Mu ...
- Python多进程-进程间数据的传递
两个进程间的数据是独立的,要进行数据传递的话可通过几个方法 Queue 通过队列来进行进程间数据的传递 # -*- coding:utf-8 -*- __author__ = "MuT6 S ...
- python 使用多进程实现并发编程/使用queue进行进程间数据交换
import time import os import multiprocessing from multiprocessing import Queue, pool ""&qu ...
- 进程间数据传递:Queue,Pipe 进程间数据共享:Manager
1.使用multiprocessing模块的Queue实现数据传递 ''' 进程间通讯: Queue,用法跟线程里的Queue一样,put,get 线程queue没有做序列化,进程queue做序列化了 ...
- [转]WINDOW进程间数据通讯以及共享内存
1.引言 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.WIN32 API提供了许多函数使我们能够方便高效地进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换,就如同 ...
- ython实现进程间的通信有Queue,Pipe,Value+Array等,其中Queue实现多个进程间的通信,而Pipe实现两个进程间通信,而Value+Array使用得是共享内存映射文件的方式,所以速度比较快
1.Queue的使用 from multiprocessing import Queue,Process import os,time,random #添加数据函数 def proc_write(qu ...
随机推荐
- salt-master命令详解
**salt-master命令** 命令行官网学习网站:http://docs.saltstack.cn/ref/cli/index.html salt salt-call salt-cp salt- ...
- adb server version (31) doesn't match this client (41); killing...
1.有时候用adb工具去连接安卓设备,或者模拟器的时候,会提示adb server version(31) doesn’t match this client(41)这样的提示.如图 提示的字面意思就 ...
- 荔枝派nano例子
买回来,先短接flash芯片的14脚,然后上电,再断开14脚,开始怎么折腾都不行,最后发现是android线的问题,换成jlink ob送的android线就能找到设备了,真崩溃 lsusb,应该能看 ...
- ubuntu连接多个realsense d435
ubuntu连接多个realsense d435 import pyrealsense2 as rs import numpy as np import cv2 import time import ...
- (原)ffmpeg中的writing_filter翻译
本文的主要目的是梳理,记录自己在学习开发ffmpeg视频滤镜的笔记.参考的主要内容是根据ffmpeg中doc下的writing_filter.txt文件以及ffmpeg的源码. author:liha ...
- light4j一个轻量级的低延时、高吞吐量、内存占用量小的API平台
1.背景(abstract) 笔者算是一个极客类型的程序员了.喜欢探索一些程序内在的原理.稳定性.自动化运维.健壮性,很多时间也会 去对程序的内存使用率.cpu使用率锱铢必较.尽量克扣掉不必要的cpu ...
- Efficient and Accurate Arbitrary-Shaped Text Detection with Pixel Aggregation Network(利用像素聚合网络进行高效准确的任意形状文本检测)
PSENet V2昨日刚出,今天翻译学习一下. 场景文本检测是场景文本阅读系统的重要一步,随着卷积神经网络的快速发展,场景文字检测也取得了巨大的进步.尽管如此,仍存在两个主要挑战,它们阻碍文字检测部署 ...
- shell中 >/dev/null 2>&1是什么意思
原文地址:http://juke.outofmemory.cn/entry/295292 我们经常能在 shell 脚本中发现 >/dev/null 2>&1 这样的语句.以前的我 ...
- Centos7中rc.local设置springboot项目开机自启动
在Centos7下,rc.local文件,开机默认是不执行的 1.进入rc.local中 路径如下图
- 前端传实体数组;后台list实体接收参数
前端页面: $.ajax({ url: url, data: JSON.stringify(data), dataType: "json", contentType: " ...