Python之旅.第九章.并发编程
Posted yangli0504
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python之旅.第九章.并发编程相关的知识,希望对你有一定的参考价值。
进程
#串行: 一个一个的运行
1、什么是程序?什么是进程?
程序说白了就是一堆文件
进程就是一个正在执行的过程/程序,所以说进程是一个抽象的概念。这个概念起源操作系统
2、什么是操作系统
定义:操作系统是位于计算机硬件与应用软件之间,用于协调、管理、控制计算机硬件与软件的资源的一种控制程序
3、操作系统的两大作用:
1、把复杂丑陋的硬件操作都封装成美丽的接口,提供给应用程序使用
2、把进程对硬件的竞争变的有序
4、多道技术(单个CPU在多个程序中切换以实现并发)
多道的产生背景是想要在单个cpu的情况下实现多个进程并发执行的效果
a、空间上的复用 (多道程序复用内存的空间)
b、时间上的复用 (多道程序复用CPU时间)
cpu遇到IO操作要切换(提升效率)
一个进程占用cpu时间过长也切(降低效率)
进程与进程之间的内存空间是互相隔离的
并发的本质:切换+保持状态
一、同一个程序执行多次是多个进程
每一个进程有一个PID
import os
print(‘爹是:‘,os.getppid()) #父的pid (pycharm.exe)
print(‘me是: ‘,os.getpid()) #自己的pid (python.exe)
二、开启子进程的两种方式
windows (createprocess) 创建子进程时子辈除了拷贝父辈的信息还创建了些自己的东西
unix (fork) 创建子进程时拷贝父辈的信息,子进程的初始状态和父辈一致
第一种(比较常用)
from multiprocessing import Process
import time
def task(name):
print(‘%s is running‘ %name)
time.sleep(3)
print(‘%s is done‘ %name)
if __name__ == ‘__main__‘:
# 在windows系统之上,开启子进程的操作一定要放到这下面
# Process(target=task,kwargs={‘name‘:‘egon‘}) #两种传参方式皆可
p=Process(target=task,args=(‘egon‘,)) #两种传参方式皆可
p.start() # 向操作系统发送请求,操作系统会申请内存空间,然后把父进程的数据拷贝给子进程,作为子进程的初始状态
print(‘======主‘)
第二种
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self,name):
super(MyProcess,self).__init__() #Process在init里面有相应设置,要遗传下来,否则报错
self.name=name
def run(self):
print(‘%s is running‘ %self.name)
time.sleep(3)
print(‘%s is done‘ %self.name)
if __name__ == ‘__main__‘:
p=MyProcess(‘egon‘)
p.start() #p.start()调用了类中的run()方法(规定)
print(‘主‘)
三、进程的内存空间相互隔离
from multiprocessing import Process
import time
x=1000
def task():
time.sleep(3)
global x
x=0
print(‘儿子死啦‘,x)
#在之前最好只有函数或变量的定义,没有具体的执行(print等)
if __name__ == ‘__main__‘:
p=Process(target=task)
p.start()
time.sleep(5)
print(x)
#在子进程中对变量x的修改不影响父进程中x的值
四、父进程等待子进程结束 p1.join()
#笨
from multiprocessing import Process
import time
x=1000
def task(n):
print(‘%s is runing‘ %n)
time.sleep(n)
if __name__ == ‘__main__‘:
start_time=time.time()
p1=Process(target=task,args=(1,))
p2=Process(target=task,args=(2,))
p3=Process(target=task,args=(3,))
p1.start()
p2.start()
p3.start()
p3.join() #3s
p1.join()
p2.join( )
print(‘主‘,(time.time() - start_time)) #3.01637601852417
#用循环
from multiprocessing import Process
import time
x=1000
def task(n):
print(‘%s is runing‘ %n)
time.sleep(n)
if __name__ == ‘__main__‘:
start_time=time.time()
p_l=[]
for i in range(1,4):
p=Process(target=task,args=(i,))
p_l.append(p)
p.start()
for p in p_l:
p.join()
print(‘主‘,(time.time() - start_time)) #3.0141923427581787
五、进程对象的其他属性
from multiprocessing import Process
import time
def task(n):
print(‘%s is runing‘ %n)
time.sleep(n)
if __name__ == ‘__main__‘:
start_time=time.time()
p1=Process(target=task,args=(1,),name=‘任务1‘)
p1.start()
print(p1.pid)
print(p1.name) #如前面不定义name,默认process-1 etc
p1.terminate() #向操作系统发请求,关闭需要一点时间
p1.join()
print(p1.is_alive())
print(‘主‘)
from multiprocessing import Process
import time,os
def task():
print(‘self:%s parent:%s‘ %(os.getpid(),os.getppid()))
time.sleep(3)
if __name__ == ‘__main__‘:
p1=Process(target=task,)
p1.start()
print(p1.pid)
print(‘主‘,os.getpid())
六、僵尸进程与孤儿进程
在unix系统中init是所有进程的爹;创建进程用fork,回收进程用waitpid
僵尸进程(有害:占用pid):子代先于父代终结,其部分信息(pid等)没有从系统中删除,需要父代回收。join中含有回收子代信息的功能。
孤儿进程(无害):父代先于子代终结,子代终结后的部分信息由init代收。
from multiprocessing import Process
import time,os
def task(n):
print(‘%s is running‘ %n)
time.sleep(n)
if __name__ == ‘__main__‘:
p1=Process(target=task,args=(1,))
p1.start()
p1.join() # join中含有回收子代信息的功能(wait)
print(‘======主‘,os.getpid())
time.sleep(10000)
以上是关于Python之旅.第九章.并发编程的主要内容,如果未能解决你的问题,请参考以下文章