20171104 python多进程编程
=====================================================================
积累:
ps -ef >1.txt 重定向到1.txt文件当中去
vim编辑器:
hjkl光标的左移,下移,上移,右移
gg移动到文档的最上方
ctrl+3 光标指向该位置上方的相同的字段
=====================================================================
1.程序和进程
程序:存储在电子设备上0与1有序组合;
进程:程序在操作系统(OS)中运行的一个抽象;
抽象是一种近似,一种简化,帮助我们认识事物和使用事物
程序与进程的关系:
一对一,一对多, (有道云笔记,谷歌浏览器)
多对一,多对多, (..........)
实例:
在ipyhton交互环境中:
In [1]: 1/3
Out[1]: 0.3333333333333333
In [2]: 0.3333333333333333
Out[2]: 0.3333333333333333
In [3]: 0.3333333333333333*3
Out[3]: 1.0
In [4]: 3+1e20
Out[4]: 1e+20
In [5]: 3+1e20-1e20
Out[5]: 0.0
In [6]: 3+(1e20-1e20)
Out[6]: 3.0 说明:python不满足结合律
意义:在做数据计算时,先(绝对值大的数据)对精度几近相似的数据进行计算
=====================================================================
2.对程序、进程、和线程进行一种抽象类似的近似
概念:
OS操作系统:公司
cpu,I/O:公司的资源
进程:公司的部门;做各种事情;部门有自己的办公区;有自己的厕所,自己的餐
厅,自己的健身房;部门要有人(进程创建以后一定有线程)
线程:部门的人;来干活的
锁:部门的厕所那把锁;健身房的那把锁;作用-限流;资源有限,需要多资源进行管
理;管理资源就需要加锁;有锁就必然会有钥匙
3.进程:OS对程序执行的一次抽象;
A:进程的组成:
数据段,代码段,进程控制块(PCB)-进程信息的控制块,公司裁员
进程控制块:
(1)进程的标识符号 pid,name
(2)进程的调度信息(进程的状态,进程的优先级,进程的关系)
(3)进程的控制信息(资源清单,信号量,互斥量,锁的信息,虚拟的地址等)
(4)处理机的信息(通用寄存器,指令计数器等)
实验:
ps #linux系统查看进程的命令
ps -aux #进程快照
top/htop #linux系统进程动态显示
linux系统中的NI:linux下的进程优先级 -20 - 19
ps linux下查看进程的命令
ps linux -aux 进程快照
top 进程动态显示
进程的主要特征:
动态性,独立性,并发性,结构性
B.几种特殊的进程:
孤儿进程:父进程创建子进程,被杀或者他杀;
僵尸进程:父进程创建子进程,子进程被杀或者自杀,父进程没有上报(系统,系统依旧分配资源,导致多余资源无法回收)
=====================================================================
3.进程中的相关名词:
进程状态:
就绪、执行、等待/阻塞(新建、终止);
注意:进程在阻塞状态时,必须先进入就绪状态,然后才能进入执行状态
进程调度:
操作系统会合理为系统中进程分配资源,供其运行;
调度算法有:时间片轮转调度;基于优先级的抢占式调度
多任务:多个软件同时运行,完成不同的功能
并发与并行:
并发:
同一时间点,多个进程同时在跑,但在及其微小的时间中看来,还是存在时间上的执行顺序的(一个部门做三件事情也是有先后顺序的);
并行:
多个核,在同一时间点,在物理意义上是真生存在多个进程同时运行;实际上只有多核操作系统,才有真正的并行(三个部门同时做三件事情)。
阻塞与非阻塞:
阻塞:进程一直在等待运行;
非阻塞:进程离开去做其他的事情
异步与同步:
同步:只有自己同时做几件事情
异步:自己买东西查东西的同时,卖家同时给予反馈
关于死锁:
死锁:进程A、进程B需要都拿到资源1,2才能执行,但是现在进程A进程占用资源1,等待资源2的释放;进程B占用资源2,等待资源1的释放,两个进程互斥,于是发生死锁
解决死锁:
(1)避免互斥 避免资源被一个进程使用;缺点,和资源本身的性质有关系;
(2)资源获取的原子性,保证所有的资源都拿到,否则都不要;缺点,效率低,当进程B只需要资源1时,也必须将资源2取出;
(3)让资源有序化(资源获取排队),缺点,效率低,例如银行家算法
上面3个方法在设计上尝试避免死锁发生;
(4)请求与保持条件,比如timeout,调度算法处理;缺点,需要确定谁放手;
上面这个方法是指在发生时进行补救
注:原子性表示一个操作序列就像一个操作一样不被打断,而不像一个操作序列一样中间容许被打断。
multiprocessing包:
python跨平台的多进程管理宝,实现本地和远程并发
支持windos、linux平台
帮助(交互环境下)
import multiprocessing
help(multiprocessing.Process)
help(fork)
单核:一个时刻只能执行一个进程的一条指令
资源:时间片
Python daemon进程:
1.后台进程;
2.主进程一结束,子进程就跟着结束(因为该属性,慎用daemon);
3.写在start之前
4.可以随时被杀死
数据结构:
队列:FIFO(First In First Out) 先进先出 例:排队买票(两个门)
栈:LIFO(Last In First Out) 先进后出 例:电梯(只有一个门)
优先队列:priority queue
进程调度:
时间片:就绪等待执行等待的东西(轮到谁执行谁);
优先级:自定义设置执行顺序
=====================================================================
程序实例(1):演示僵尸进程,解释见下方文件
from multiprocessing import Process
import time
def t1(interval):
for i in range(interval):
# while True:
time.sleep(1)
print('child '+time.ctime())
if __name__ == '__main__':
P = Process(target=t1,args=(5,))
# P.daemon = True
P.start()
# P.join()
time.sleep(2)
print('main process')
while True:
# p.terminate()
time.sleep(2)
print('mian '+time.ctime())
========================================================================
程序实例(2):#演示子进程一定会被父进程接管,解释键下方文件
import os
import time
pid = os.fork()
if pid < 0:
print('fork error')
elif pid == 0:
# time.sleep(1)
print('child id %d,parent id %d' % (os.getpid(),os.getppid()))
else:
print('parent id %d,child id %d' % (os.getpid(),pid))
========================================================================
详细解释:程序实例(1):演示僵尸进程,解释见下方文件
from multiprocessing import Process #此句已经是主进程
import time
def t1(interval):
for i in range(interval): #设置子进程的执行次数
# while True: #设置死循环 子进程反复执行
time.sleep(1) #睡1秒
print('child '+time.ctime()) #打印时间,按某种格式打印时间
if __name__ == '__main__': #如果存在父子进程关系,父进程会等子进程,等子进程执行结束,父进程再结束
P = Process(target=t1,args=(5,))#创立进程,后面是创建元组,生成可迭代对象使子进程执行5次
# P.daemon = True #守卫进程语句:一旦主进程结束,子进程立刻结束,放在start()之前
P.start()
# P.join() #等待进程语句,父进程一定会等待子进程,使得守卫语句失效,变成正常的父子进程关系:父等待子进程结束
time.sleep(2) #睡眠状态 兄弟关系的进程会抢占资源谁执行都不一定
print('main process') # 主进程再这里已经结束,因为父子进程关系,父进程会等待子进程执行结束,不会在这这里结束
while True: #子进程在这里开始执行
# p.terminate() #结束进程语句 子进程被杀成为僵尸进程,但是系统没有收回资源
time.sleep(2)
print('mian '+time.ctime())
#tarena@tedu:~/aid1709$ ipython3 1104.py
child Sat Nov 4 19:54:04 2017
main process
child Sat Nov 4 19:54:05 2017
child Sat Nov 4 19:54:06 2017
mian Sat Nov 4 19:54:07 2017
child Sat Nov 4 19:54:07 2017
child Sat Nov 4 19:54:08 2017
mian Sat Nov 4 19:54:09 2017
mian Sat Nov 4 19:54:11 2017
mian Sat Nov 4 19:54:13 2017
========================================================================
详细解释:程序实例(2):#演示子进程一定会被父进程接管,解释键下方文件
import os #主进程已经开始
import time
pid = os.fork() #fork为父进程创建了子进程,返回两个值!!创建时后立刻抛弃父子关系,成为兄弟进程,两者并行执行,父进程不会等待子进程结束以后再结束
if pid < 0:
print('fork error')
elif pid == 0: # Return 0 to child process, pid = os.fork(),如果是子进程返回0
time.sleep(1) #子进程睡眠,成为孤儿进程,睡醒之后由系统接管,系统成为其父进程;1秒睡眠时间对于cpu而言时间很长,两个进程并发执行
print('child id %d,parent id %d' % (os.getpid(),os.getppid())) #子进程被接管
else:
print('parent id %d,child id %d' % (os.getpid(),pid))#两者并行执行,谁先执行不一定
# tarena@tedu:~/aid1709$ python3 11042.py
# parent id 9564,child id 9565 #子进程睡眠,父进程进入else语句
# tarena@tedu:~/aid1709$ child id 9565,parent id 1873 子进程睡醒,没有父进程,被系统接管,生成新的父进程
# 父进程结束 子进程由操作系统接管 ps -aux |grep 1751
# fork()
# Fork a child process.
# Return 0 to child process and PID of child to parent process.
========================================================================
作业:
(1)设置优先级1-20,做一个模拟os的调度程序:某一时刻,四个进程:
Watch TV: random优先级 import rnadom
Listen to music: random优先级
Print Doc: 4
Write Doc: 4
创建队列,信息放进队列,模拟队列的调度(观察取数情况,验证时间片)
(2)多进程定期器:每一个小时,你的定时器提示你:不要coding,休息一下吧!
提示的同时显示当前进程的pid,name,os模块设置优先级
(3)通过一个进程池实现
文件夹下大量文件拷贝;至少500个文件,有方法证明你的拷贝的文件是ok的
预期过程:
input 四个进程的信息
output 打印出四个进程谁先输入输出(查看是时间片还是优先级调度)
多进程在队列中获取信息,发生阻塞时等,或者timeout(2秒超时退出),或者get_nowait()(立刻取,没有就不处理,直接退出)
提示:
递归
p = queue.PriorityQueue() 创建队列
help(p.get)
help(queue.PriorityQueue)
| get(self, block=True, timeout=None)
| Remove and return an item from the queue.
|
| If optional args 'block' is true and 'timeout' is None (the default),
| block if necessary until an item is available. If 'timeout' is
| a non-negative number, it blocks at most 'timeout' seconds and raises
| the Empty exception if no item was available within that time.
| Otherwise ('block' is false), return an item if one is immediately
| available, else raise the Empty exception ('timeout' is ignored
| in that case).
|
| get_nowait(self)
| Remove and return an item from the queue without blocking.
|
| Only get an item if one is immediately available. Otherwise
| raise the Empty exception.
help(p.get_nowait)
=====================================================================
积累:
ps -ef >1.txt 重定向到1.txt文件当中去
vim编辑器:
hjkl光标的左移,下移,上移,右移
gg移动到文档的最上方
ctrl+3 光标指向该位置上方的相同的字段
=====================================================================
1.程序和进程
程序:存储在电子设备上0与1有序组合;
进程:程序在操作系统(OS)中运行的一个抽象;
抽象是一种近似,一种简化,帮助我们认识事物和使用事物
程序与进程的关系:
一对一,一对多, (有道云笔记,谷歌浏览器)
多对一,多对多, (..........)
实例:
在ipyhton交互环境中:
In [1]: 1/3
Out[1]: 0.3333333333333333
In [2]: 0.3333333333333333
Out[2]: 0.3333333333333333
In [3]: 0.3333333333333333*3
Out[3]: 1.0
In [4]: 3+1e20
Out[4]: 1e+20
In [5]: 3+1e20-1e20
Out[5]: 0.0
In [6]: 3+(1e20-1e20)
Out[6]: 3.0 说明:python不满足结合律
意义:在做数据计算时,先(绝对值大的数据)对精度几近相似的数据进行计算
=====================================================================
2.对程序、进程、和线程进行一种抽象类似的近似
概念:
OS操作系统:公司
cpu,I/O:公司的资源
进程:公司的部门;做各种事情;部门有自己的办公区;有自己的厕所,自己的餐
厅,自己的健身房;部门要有人(进程创建以后一定有线程)
线程:部门的人;来干活的
锁:部门的厕所那把锁;健身房的那把锁;作用-限流;资源有限,需要多资源进行管
理;管理资源就需要加锁;有锁就必然会有钥匙
3.进程:OS对程序执行的一次抽象;
A:进程的组成:
数据段,代码段,进程控制块(PCB)-进程信息的控制块,公司裁员
进程控制块:
(1)进程的标识符号 pid,name
(2)进程的调度信息(进程的状态,进程的优先级,进程的关系)
(3)进程的控制信息(资源清单,信号量,互斥量,锁的信息,虚拟的地址等)
(4)处理机的信息(通用寄存器,指令计数器等)
实验:
ps #linux系统查看进程的命令
ps -aux #进程快照
top/htop #linux系统进程动态显示
linux系统中的NI:linux下的进程优先级 -20 - 19
ps linux下查看进程的命令
ps linux -aux 进程快照
top 进程动态显示
进程的主要特征:
动态性,独立性,并发性,结构性
B.几种特殊的进程:
孤儿进程:父进程创建子进程,被杀或者他杀;
僵尸进程:父进程创建子进程,子进程被杀或者自杀,父进程没有上报(系统,系统依旧分配资源,导致多余资源无法回收)
=====================================================================
3.进程中的相关名词:
进程状态:
就绪、执行、等待/阻塞(新建、终止);
注意:进程在阻塞状态时,必须先进入就绪状态,然后才能进入执行状态
进程调度:
操作系统会合理为系统中进程分配资源,供其运行;
调度算法有:时间片轮转调度;基于优先级的抢占式调度
多任务:多个软件同时运行,完成不同的功能
并发与并行:
并发:
同一时间点,多个进程同时在跑,但在及其微小的时间中看来,还是存在时间上的执行顺序的(一个部门做三件事情也是有先后顺序的);
并行:
多个核,在同一时间点,在物理意义上是真生存在多个进程同时运行;实际上只有多核操作系统,才有真正的并行(三个部门同时做三件事情)。
阻塞与非阻塞:
阻塞:进程一直在等待运行;
非阻塞:进程离开去做其他的事情
异步与同步:
同步:只有自己同时做几件事情
异步:自己买东西查东西的同时,卖家同时给予反馈
关于死锁:
死锁:进程A、进程B需要都拿到资源1,2才能执行,但是现在进程A进程占用资源1,等待资源2的释放;进程B占用资源2,等待资源1的释放,两个进程互斥,于是发生死锁
解决死锁:
(1)避免互斥 避免资源被一个进程使用;缺点,和资源本身的性质有关系;
(2)资源获取的原子性,保证所有的资源都拿到,否则都不要;缺点,效率低,当进程B只需要资源1时,也必须将资源2取出;
(3)让资源有序化(资源获取排队),缺点,效率低,例如银行家算法
上面3个方法在设计上尝试避免死锁发生;
(4)请求与保持条件,比如timeout,调度算法处理;缺点,需要确定谁放手;
上面这个方法是指在发生时进行补救
注:原子性表示一个操作序列就像一个操作一样不被打断,而不像一个操作序列一样中间容许被打断。
multiprocessing包:
python跨平台的多进程管理宝,实现本地和远程并发
支持windos、linux平台
帮助(交互环境下)
import multiprocessing
help(multiprocessing.Process)
help(fork)
单核:一个时刻只能执行一个进程的一条指令
资源:时间片
Python daemon进程:
1.后台进程;
2.主进程一结束,子进程就跟着结束(因为该属性,慎用daemon);
3.写在start之前
4.可以随时被杀死
数据结构:
队列:FIFO(First In First Out) 先进先出 例:排队买票(两个门)
栈:LIFO(Last In First Out) 先进后出 例:电梯(只有一个门)
优先队列:priority queue
进程调度:
时间片:就绪等待执行等待的东西(轮到谁执行谁);
优先级:自定义设置执行顺序
=====================================================================
程序实例(1):演示僵尸进程,解释见下方文件
from multiprocessing import Process
import time
def t1(interval):
for i in range(interval):
# while True:
time.sleep(1)
print('child '+time.ctime())
if __name__ == '__main__':
P = Process(target=t1,args=(5,))
# P.daemon = True
P.start()
# P.join()
time.sleep(2)
print('main process')
while True:
# p.terminate()
time.sleep(2)
print('mian '+time.ctime())
========================================================================
程序实例(2):#演示子进程一定会被父进程接管,解释键下方文件
import os
import time
pid = os.fork()
if pid < 0:
print('fork error')
elif pid == 0:
# time.sleep(1)
print('child id %d,parent id %d' % (os.getpid(),os.getppid()))
else:
print('parent id %d,child id %d' % (os.getpid(),pid))
========================================================================
详细解释:程序实例(1):演示僵尸进程,解释见下方文件
from multiprocessing import Process #此句已经是主进程
import time
def t1(interval):
for i in range(interval): #设置子进程的执行次数
# while True: #设置死循环 子进程反复执行
time.sleep(1) #睡1秒
print('child '+time.ctime()) #打印时间,按某种格式打印时间
if __name__ == '__main__': #如果存在父子进程关系,父进程会等子进程,等子进程执行结束,父进程再结束
P = Process(target=t1,args=(5,))#创立进程,后面是创建元组,生成可迭代对象使子进程执行5次
# P.daemon = True #守卫进程语句:一旦主进程结束,子进程立刻结束,放在start()之前
P.start()
# P.join() #等待进程语句,父进程一定会等待子进程,使得守卫语句失效,变成正常的父子进程关系:父等待子进程结束
time.sleep(2) #睡眠状态 兄弟关系的进程会抢占资源谁执行都不一定
print('main process') # 主进程再这里已经结束,因为父子进程关系,父进程会等待子进程执行结束,不会在这这里结束
while True: #子进程在这里开始执行
# p.terminate() #结束进程语句 子进程被杀成为僵尸进程,但是系统没有收回资源
time.sleep(2)
print('mian '+time.ctime())
#tarena@tedu:~/aid1709$ ipython3 1104.py
child Sat Nov 4 19:54:04 2017
main process
child Sat Nov 4 19:54:05 2017
child Sat Nov 4 19:54:06 2017
mian Sat Nov 4 19:54:07 2017
child Sat Nov 4 19:54:07 2017
child Sat Nov 4 19:54:08 2017
mian Sat Nov 4 19:54:09 2017
mian Sat Nov 4 19:54:11 2017
mian Sat Nov 4 19:54:13 2017
========================================================================
详细解释:程序实例(2):#演示子进程一定会被父进程接管,解释键下方文件
import os #主进程已经开始
import time
pid = os.fork() #fork为父进程创建了子进程,返回两个值!!创建时后立刻抛弃父子关系,成为兄弟进程,两者并行执行,父进程不会等待子进程结束以后再结束
if pid < 0:
print('fork error')
elif pid == 0: # Return 0 to child process, pid = os.fork(),如果是子进程返回0
time.sleep(1) #子进程睡眠,成为孤儿进程,睡醒之后由系统接管,系统成为其父进程;1秒睡眠时间对于cpu而言时间很长,两个进程并发执行
print('child id %d,parent id %d' % (os.getpid(),os.getppid())) #子进程被接管
else:
print('parent id %d,child id %d' % (os.getpid(),pid))#两者并行执行,谁先执行不一定
# tarena@tedu:~/aid1709$ python3 11042.py
# parent id 9564,child id 9565 #子进程睡眠,父进程进入else语句
# tarena@tedu:~/aid1709$ child id 9565,parent id 1873 子进程睡醒,没有父进程,被系统接管,生成新的父进程
# 父进程结束 子进程由操作系统接管 ps -aux |grep 1751
# fork()
# Fork a child process.
# Return 0 to child process and PID of child to parent process.
========================================================================
作业:
(1)设置优先级1-20,做一个模拟os的调度程序:某一时刻,四个进程:
Watch TV: random优先级 import rnadom
Listen to music: random优先级
Print Doc: 4
Write Doc: 4
创建队列,信息放进队列,模拟队列的调度(观察取数情况,验证时间片)
(2)多进程定期器:每一个小时,你的定时器提示你:不要coding,休息一下吧!
提示的同时显示当前进程的pid,name,os模块设置优先级
(3)通过一个进程池实现
文件夹下大量文件拷贝;至少500个文件,有方法证明你的拷贝的文件是ok的
预期过程:
input 四个进程的信息
output 打印出四个进程谁先输入输出(查看是时间片还是优先级调度)
多进程在队列中获取信息,发生阻塞时等,或者timeout(2秒超时退出),或者get_nowait()(立刻取,没有就不处理,直接退出)
提示:
递归
p = queue.PriorityQueue() 创建队列
help(p.get)
help(queue.PriorityQueue)
| get(self, block=True, timeout=None)
| Remove and return an item from the queue.
|
| If optional args 'block' is true and 'timeout' is None (the default),
| block if necessary until an item is available. If 'timeout' is
| a non-negative number, it blocks at most 'timeout' seconds and raises
| the Empty exception if no item was available within that time.
| Otherwise ('block' is false), return an item if one is immediately
| available, else raise the Empty exception ('timeout' is ignored
| in that case).
|
| get_nowait(self)
| Remove and return an item from the queue without blocking.
|
| Only get an item if one is immediately available. Otherwise
| raise the Empty exception.
help(p.get_nowait)