Python-进程(1)
操作系统发展史
穿孔卡片
早期程序员使用穿孔卡片编程,
只有一个计算机机房,一次只能读取一个卡片,
所以造成CPU的利用率极低
联机批处理系统
后来出现了联机批处理系统,支持多用户去使用一个计算机机房
统计批处理系统
再后来出现了脱机批处理系统,有了高速磁盘,提高了文件的读取速度,优点是提高了CPU的利用率
单道
基于单核情况下研究分为单道和多道,单道即多个程序在使用CPU时是串行运行
多道技术
当代计算机使用的技术 是多道技术
空间上复用
一个CPU可以提供多个用户去使用
时间上复用
切换 + 保存状态
若CPU 遇到 IO 操作,会立即将当前执行程序CPU使用权断开
优点:CPU利用率高
若一个程序使用CPU的时间过长,会立即将当前执行程序CPU使用权断开
缺点:程序执行效率低
并行与并发
并行:指的是看起来像同时在运行,其实是多个程序不停 切换 + 保存状态
并发:真正意义上的同时运行,在多核(多个CPU)情况下,同时执行多个程序
进程
执行中的程序叫做进程(Process),是一个动态的概念
在linux中查看进程信息:top
61546 root 20 0 15028 1196 836 R 4.4 0.1 0:00.35 top
程序与进程
程序:一堆代码文件
进程:一堆代码文件运行的过程
进程调度
当代操作系统调度:
时间片轮转法 + 分级反馈队列
1、 先来先服务调度
a,b 程序,若a程序先来,先占用CPU
缺点:程序a先使用,程序b必须等待程序a使用CPU完毕之后才能使用
2、 短作业优先调度
a,b程序,谁的用时短,优先调度谁使用CPU
缺点:
若程序a使用时间最长,有N个程序使用时间段,
必须等待所有用时短的程序结束后才能使用
3、 时间片轮转法
CPU执行的时间1秒钟,若加载N个程序,将时间等分成多n个时间片供程序执行
4、 分级反馈队列
将执行优先级分多层级别
1级:优先级最高
2级:优先级第二,以此类推
。。。
进程的三个状态
就绪态
所有程序创建时都会进入就绪态,准备调度
运行态
调度后的进程,进入运行态
阻塞态
凡是遇到IO操作的进程,都会进入阻塞态
若IO结束,必须重新进入就绪态
同步和异步
指的是提交任务的方式
同步:若有两个任务需要提交,在提交第一个任务时,必须等待该任务执行结束后,才能继续提交并执行第二个任务。
同步演示:
# coding=utf-8
import time
def test():
# 睡一秒 也是IO操作
time.sleep(1)
# 计算操作不属于IO操作
n = 0
for i in range(1000):
n += i
print(n)
if __name__ == '__main__':
test() # 先执行完test函数,再执行下面的代码,同步操作
print("hello world")
异步:
若有两个任务需要提交,在提交第一个任务时,不需要原地等待,立即可以提交并执行第二个任务。
阻塞与非阻塞
阻塞:
阻塞态,遇到IO 一定会阻塞
非阻塞:
就绪态
运行态
创建进程
创建进程的两种方式
'''
创建进程方式一:
'''
from multiprocessing import Process
import time
def task(name):
print(f"{name} 子任务start...")
time.sleep(2)
print(f"{name} 子任务end....")
if __name__ == '__main__':
p = Process(target=task,args=("qinyj",))
p.start()
print("主进程...")
代码解释:
p = Process(target=task,args=("qinyj",)):实例化一个对象p,Process类参数:target=函数名,args=函数参数(必须是元组 + ,)
p.start():向操作系统发送指令开启一个子进程,至于这个子进程什么时候启动,要看机器的硬件性能
打印结果:
主进程... qinyj 子任务start... qinyj 子任务end....
'''
创建进程方式二:
'''
from multiprocessing import Process
import time
class MyProcess(Process):
def run(self):
print(f"子任务 start...")
time.sleep(2)
print(f"子任务 end....")
if __name__ == '__main__':
p = MyProcess()
p.start()
print("主进程...")
代码解释
p = MyProcess():实例化自己写的一个类,这个类必须继承Process
p.start():向操作系统发送指令开启一个子进程,至于这个子进程什么时候启动,要看机器的硬件性能
打印结果:
主进程... 子任务 start... 子任务 end....
那么为什么我们要用if name == 'main':?,
是因为Windows在执行这个文件的时候,会自动import导入这个文件,导入这个文件相当于又重新执行了一遍里面的代码,这样子进程就重新又被创建了出来,子进程然后又运行到创建子进程的代码。。。无限循环,最后报错。那么在Linux中执行这个文件不会自动import导入,它所创建的子类代码仅仅是执行的函数代码,fork了一块新的内存空间执行这个函数,所以不会报错
那么我们为了统一使用,最好加上if name == 'main':,意思是作为执行文件执行的时候,判断它的名字,条件符合了再执行下面的代码,这样无论哪个平台运行代码都不会报错。
join的用法
# coding=utf-8
from multiprocessing import Process
import time
def task(name):
print(f"{name} 子任务 start...")
time.sleep(2)
print(f"{name} 子任务 end...")
if __name__ == '__main__':
p1 = Process(target=task,args=("qinyj",))
p2 = Process(target=task,args=("jack",))
p3 = Process(target=task,args=("qyj",))
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
print("主进程...")
p.join:用来告诉操作系统,让子进程结束后,父进程在结束
进程间数据相互隔离
# coding=utf-8
from multiprocessing import Process
x = 100
def func():
print("函数执行")
global x
x = 200
print(f"函数内部的x:{x}")
if __name__ == '__main__':
p = Process(target=func)
p.start()
p.join()
print(f"主进程的x:{x}")
函数执行
函数内部的x:200
主进程的x:100
进程对象属性
# coding=utf-8
from multiprocessing import Process
from multiprocessing import current_process
import os
import time
def task(name):
print(f"{name} 子任务start...",f"子进程进程号:{current_process().pid}")
print(f"{name} 子任务start...",f"子进程进程号:{os.getpid()}",f"父进程进程号{os.getppid()}")
time.sleep(200)
print(f"{name} 子任务end.....",current_process().pid)
if __name__ == '__main__':
p = Process(target=task,args=("qinyj",))
p.start()
time.sleep(1)
print(p.is_alive())
p.terminate()
time.sleep(1)
print(p.is_alive())
p.join()
print("主程序start..",os.getpid())
print("主主进程start...",os.getppid())
qinyj 子任务start... 子进程进程号:9132
qinyj 子任务start... 子进程进程号:9132 父进程进程号7348
True
False
主程序start.. 7348
主主进程start... 2812
代码解释:
p.terminate():直接告诉操作系统,终止子进程
print(p.is_alive()):打印子进程的存活状态(True or False)
current_process().pid:获取当前的pid号
os.getpid():获取当前的pid号
os.getppid():获取当前父进程的pid号
cmd中查看进程号:tasklist |findstr 进程号
C:\Users\Administrator>tasklist | findstr 6724 # 查看子进程pid号即python解释器的进程
python.exe 6724 Console 1 30,576 K
C:\Users\Administrator>tasklist | findstr 2812 # 查看主进程pid号即pycharm解释器的进程
pycharm64.exe 2812 Console 1 909,528 K
由进程产生的pid号会自动 由主进程回收,如果子进程存在,主进程死掉了,那么子进程就是僵尸进程
两种进程号回收的方法条件:
1、 join:主进程可以等待子进程结束 pid一起被回收
2、 主进程正常结束,守护进程开启,子进程与主进程 pid被回收
守护进程
# coding=utf-8
from multiprocessing import Process
from multiprocessing import current_process
import os
import time
def task(name):
print(f"{name} 子进程start...",current_process().pid)
time.sleep(5)
print(f"{name} 子进程end...",current_process().pid)
if __name__ == '__main__':
p = Process(target=task,args=("qinyj",))
p.daemon = True
p.start()
time.sleep(1) # 停留1s 让子进程启动
print("主进程启动...")
qinyj 子进程start... 5680
主进程启动...
代码解释:
p.daemon = True:添加守护进程,True
守护进程表示的是 主进程死的时候,无论子进程在干什么,直接干掉子进程,跟着主程序一起死掉
僵尸进程
僵尸进程指的是子进程已经结束,但pid号还存在没有被销毁,可以比喻人死了,身份证还没有注销,那这个pid就会一直被占用,那么操作系统的进程号是有限的,如果产生大量的僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程,此为僵尸进程的危害,应当避免
那么我们可以通过查找这个pid号kill 手动杀掉回收
僵尸进程的缺点:占用pid号,占用操作系统的资源
孤儿进程
孤儿进程指的是子进程还在执行,但父进程意外结束,但是有操作系统优化机制,会提供一个孤儿院,专门帮那些已经死了的主进程 回收那些没有父亲的子进程,在linux操作系统中,这个孤儿院就是init进程,pid号是1
1 root 20 0 19364 644 424 S 0.0 0.1 0:17.45 init
Python-进程(1)的更多相关文章
- python——进程基础
我们现在都知道python的多线程是个坑了,那么多进程在这个时候就变得很必要了.多进程实现了多CPU的利用,效率简直棒棒哒~~~ 拥有一个多进程程序: #!/usr/bin/env python #- ...
- 使用gdb调试Python进程
使用gdb调试Python进程 有时我们会想调试一个正在运行的Python进程,或者一个Python进程的coredump.例如现在遇到一个mod_wsgi的进程僵死了,不接受请求,想看看究竟是运行到 ...
- python进程、线程、协程(转载)
python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资 ...
- Python进程、线程、协程详解
进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配.任务的调度. ...
- python进程池剖析(一)
python中两个常用来处理进程的模块分别是subprocess和multiprocessing,其中subprocess通常用于执行外部程序,比如一些第三方应用程序,而不是Python程序.如果需要 ...
- python——进程、线程、协程
Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env pytho ...
- python/进程线程的总结
python/进程线程的总结 一.进程和线程的描述: 进程:最小的资源管理单位 线程:最小的执行单位 执行一个进程时就默认执行一个线程(主线程) 进程和线程的工作方式: 串行: 假如共有A.B.C任务 ...
- python 进程介绍 进程简单使用 join 验证空间隔离
一.多道程序设计技术(详情参考:https://www.cnblogs.com/clschao/articles/9613464.html) 所谓多道程序设计技术,就是指允许多个程序同时进入内存并运行 ...
- Python 进程之间共享数据
最近遇到多进程共享数据的问题,到网上查了有几篇博客写的蛮好的,记录下来方便以后查看. 一.Python multiprocessing 跨进程对象共享 在mp库当中,跨进程对象共享有三种方式,第一种 ...
- python进程、多进程
进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在当 ...
随机推荐
- 《转》python基础下
转自http://www.cnblogs.com/BeginMan/archive/2013/04/12/3016323.html 一.数字 在看<Python 核心编程>的时候,我就有点 ...
- VMware 安装android-x86系统。
首先先安装 VMware 虚拟机,并下载 android-x86_64-8.1-r2.iso 系统. VMware安装完成后,打开VMware Workstation,单击“创建新的虚拟机”,或者在菜 ...
- JS对象 substring() 方法用于提取字符串中介于两个指定下标之间的字符。
提取字符串substring() substring() 方法用于提取字符串中介于两个指定下标之间的字符. 语法: stringObject.substring(starPos,stopPos) 参 ...
- 从别人git下载项目下来然后运行
1点击clone or download 2.自由选择 3.拉到你想放的位置,我是放到桌面上的 4. cmd 打开,进入你 的下载到桌面的项目 5. # install dependencies n ...
- php+jquery 上拉加载
<script type="text/javascript"> var resflow = true,pages =2; var ps=$("#ids&quo ...
- c++ strlen() 函数
{ char *buf = new char[1024]; ZeroMemory(buf,1024) for(int i = 0; i < 1023; i++) { buf[i] = '5'; ...
- 微信公众号开发API接口大全
在本文中,我们列出微信公众平台上可以使用的API接口以及举例如何在微信公众平台调用这些接口实现相应的功能. 接口调用说明: ① Appkey请使用的微信公众号,不要使用默认的trailuser ② 接 ...
- day27 模块:正则re, configparser, subprocess
Python之路,Day15 = Python基础15 re 模块补充 ret = re.findall("c.d", "abc\nd", re.S) # 后面 ...
- luoguP2580 于是他错误的点名开始了 [Trie]
题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 他会一边搓炉石一边点名以至于有一天他连续点到了某个同学两次,然后正好被路过的校长发现了然后就是一顿欧拉欧拉欧拉(详情请见已结束比赛CON900). ...
- Delphi窗体间发送消息或字符串
在Delphi 开发中,常常应用到窗体消息传递,以达成某种操作要求,以下列举一个应用的例子,供大家参考. 自定义过程/函数方法://发送字符串到指字句柄的窗口中 (接收窗体需用发送时的消息常量WM_C ...