进程

 

进程理论

程序:一堆代码
进程:正在运行的程序
进程是一个实体。每一个进程都有他独立的内存空间

同步和异步:针对任务的提交方式
同步:提交任务之后原地等待任务的返回结果,期间不做任何事
异步:提交任务之后,不等待任务的返回结果,执行运行下一行代码

阻塞与非阻塞:针对程序运行的状态
阻塞:遇到IO操作 >>>阻塞态
非阻塞:就绪或者运行态 >>>就绪态,运行态

开启进程的两种运行方式

方法一:
from multiprocessing import Process

def task(name)
print(name)

#在windows系统中,因为是以导包的方式来给新的子进程添加上与主进程相同的属性, 所以一定要在文件自执行的情况下运行,不然会进入死循环
if __name__='__main__':
   #task不能加上括号,不然会直接执行,因为函数的调用优先级是最高的
   p=Process(target=task,args=('wo',))
   p.start()#发送型号给操作系统,让操作系统创建一个新的进程
   pritn('主')

方法二
from multiprocess import Process

class Myprocess(Process):
   def __init__(self,name):
       self.name=name
       super().__init__()#在添加自己的属性后,完全的copy父类中的init
       
def run(self):#必须是run因为run其实是Process的内置方法
       print('%s is running'%self.name)
       
if __name__='__main__':
   p=Myprocess('wo')
   p.start()
   print('主')      

进程对象的join方法

方法一:
from multiprocessing import Process

def task(name)
print(name)
if __name__='__main__':
   lis=[]
   for i in range(1,4)
       p=Process(target=task,args=('%s'%i,))
       p.start()
       lis.append(p)
   for j in lis:
  p.join()#在子进程全部结束后才会执行主进程,同时join会清理子进程的全部内存(包括PID信息等数据),子程序之间互不影响,只针对主进程有影响。
   pritn('主')

进程之间内存隔离

from multiprocessing import Process
a=100
def task()
global a
   a=0
if __name__='__main__':
   p==Process(target=task)
   p.start()
   p.join()#确保子进程优先执行
   print(a)# 结果为100
#结果为100说明,主进程与子进程虽然共享一个内存空间,这其实就是多道技术中空间上复用的一种体现,但是两者直接是存在物理隔离的,所以互不影响    

进程对象其他相关方法

得到pid的方法一
from multiprocessing import Process,current_process
def task()
print(curre_process().pid)#打印子进程的pid
   
if __name__='__main__':
   p==Process(target=task)
   p.start()
   print(current_process().pid)#打印主进程的pid

方法二
from multiprocessing import Process
import os
def task()
print(os.getpid())#打印子进程的pid
   print(os.getppid())#打印子进程的父进程的pid(这里其实就是主进程)
   
if __name__='__main__':
   p==Process(target=task)
   p.start()
   print(os.getpid())#打印主进程的pid
   print(os.getppid())#取决于运行python程序的应用软件  

僵尸进程与孤儿进程

僵尸进程:子进程运行结束后,内存释放,但是仍然占有pid等数据信息,提供父进程使用。
二种情况下会回收子进程的pid信息
1.父进程正常结束
   2.join方法
孤儿进程:父进程意外死亡
linux中:init就像是孤儿院,用来回收孤儿进程所占用的资源
   ps aux |grep 'Z'

守护进程

进程创建守护进程
  其一:守护进程会在主进程代码执行结束后就终止
  其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children
注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止

互斥锁

1.牺牲效率来保证了数据的安全
2.锁一定要在主进程中创建,在子进程中使用
3.解决多个进程操作同一份数据,造成数据不安全的情况
4.加锁会把并发变成串行
5.一把锁不能多人使用,没有抢到的只能一直等待锁释放

#抢票案例,文件中的数据为{"cart":1}
from multiprocessing import Process,Lock #导入Lock模块
import json
import time
import os

def look(name):
   with open('a','r')as r:
       num=json.load(r)
       print('%s查询还有%s张票'%(name,num['cart']))

def get(name):
   with open('a','r')as r:
       num = json.load(r)
   time.sleep(3) #模拟网络延时
   if num['cart']>= 1:
       num['cart']-=1
       with open('a','w')as w:
           json.dump(num,w)
           print('%s购票成功'%name)
   else:
       print('没有票了')

def run(name,lock1):
   look(name)
   lock1.acquire()   #抢锁
   get(name)
   lock1.release() #释放锁

if __name__ == '__main__':
   lock1=Lock() #其实就是生产一个对象
   for i in range(1,4):
       p=Process(target=run,args=(i,lock1))
       p.start()
   print('RUA')

 

posted @ 2019-05-06 16:34  Mr-Bear  阅读(128)  评论(0编辑  收藏  举报