并发编程 07.03

1.守护进程

主进程创建守护进程

  1. 守护进程会在主进程代码执行结束后就终止
  2. 守护进程内无法再开启子进程,否则会抛出异常

进程之间是相互独立的,主进程代码运行结束,守护进程随即终止

from multiprocessing import Process
import time
def task():    
    print('The_child_process is run')    
    time.sleep(3)    
    print('The_child_process is over')
if __name__ == '__main__':    
    p = Process(target=task)    
    p.daemon = True #一定要在p.start()前设置,设置p为守护进程,禁止p创建子进程,并且父进程代码执行结束,p即终止运行   
    p.start()    
    print('The main process is run')    
    time.sleep(3)    
    print('The main process is over')

2.进程安全问题

#并发运行,效率高,但竞争同一打印终端,带来了打印错乱
from multiprocessing import Process
def task1():    
    for i in range(1000):              
    print(1)
    
    for i in range(1000):        
    print('--------name is nick')        
    print('--------height is 1.7' )        
    print('--------weight is 60')
    
def task2():    
    for i in range(1000):               
    print(2)
    
    for i in range(1000):        
    print('++++++++name is bgon')        
    print('++++++++height is 1.65')        
    print('++++++++weight is 70')
    
if __name__ == '__main__':    
    p1 = Process(target=task1)    
    p2 = Process(target=task2) 
    
    p1.start()    
    p1.join()
    
    p2.start()

3.互斥锁

进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,

而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理

#由并发变成了串行,牺牲了运行效率,但避免了竞争
from multiprocessing import Process, Lock
import time,randomdef task1(mutex):

for i in range(1000):        
print(1)

mutex.acquire() #加锁    
time.sleep(random.random())    
print("-------name is nick")    
time.sleep(random.random())    
print("-------gender is girl")    time.sleep(random.random())    
print("-------age is 18")    
mutex.release() #解锁

def task2(mutex): 

for i in range(10000):        
print(2)

mutex.acquire() #加锁    
time.sleep(random.random())    
print("++++++++name is bgon")    
time.sleep(random.random())    
print("++++++++gender is oldman")    time.sleep(random.random())    
print("++++++++age is 48")    
mutex.release() #解锁if __name__ == '__main__':    
mutex = Lock() 

print('the locked is created')    
p1 = Process(target=task1,args=(mutex,))    
p2 = Process(target=task2, args=(mutex,))  

p1.start()    
p2.start()

4.锁的原理

def task():
    global lock
    if lock == False:
        lock = True
        open('.txt','wt')
        lock = False
#加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,没错,速度是慢了,但牺牲了速度却保证了数据安全。
虽然可以用文件共享数据实现进程间通信,但问题是:
1.效率低(共享数据基于文件,而文件是硬盘上的数据)
2.需要自己加锁处理
#因此我们最好找寻一种解决方案能够兼顾:1、效率高(多个进程共享一块内存的数据)2、帮我们处理好锁问题。这就是mutiprocessing模块为我们提供的基于消息的IPC通信机制:队列和管道。
1 队列和管道都是将数据存放于内存中
2 队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来,
我们应该尽量避免使用共享数据,尽可能使用消息传递和队列,避免处理复杂的同步和锁问题,而且在进程数目增多时,往往可以获得更好的可获展性。

5.锁的案例,模拟抢票

from multiprocess import Process, Lock
import json

def search():
    with open('.json') as fr:
        data = json.load(fr)
        print('The remaining votes',data[''count"])
                                        
def get():
     with open('.json') as fr:
     	  data =json.load(fr)
          if data["count"] > 0:
              data["count"] -= 1
               with open('.json','wt')as fw:
                    json.dump(data,fw)
                     print('buy ticket is successful')                    
def task(mutex):
    search()
    mutex.acquire()                                    
    get()
    mutex.release()
                                         
if __name__ == '__main__':
    mutex = Lock()
    for i in range(5):
        p = Process(target=task,args=(mutex,))
        p.start()

6.Manager的使用

from  multiprocessing import Process,Lock,Manager
import time
def task(data,lock):
    lock.acquire()
    num = data[0]
    time.sleep(0.3)
    data[0] = num - 1
    lock.release()
    print('The_child_process is over')

if __name__ == '__main__':
    d = [100]
    m = Manager() #创建一个管理器
    syncdict = m.list(d) # 让管理器创建一个进程同步的字典

    lock = Lock() #创建一个锁

    ps = []
    for i in range(10):
        p = Process(target=task,args=(syncdict,lock))
        p.start()
        ps.append(p)

    for p in ps:
        p.join()

    print(d)
    print(syncdict)

7.进程队列

进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的

from multiprocessing import Quene
q = Quene(2) # 创建队列 并且同时只能存储2个元素
q.put(1)
q.put(2)
# q.put(3,block=True,timeout=3) # 默认是阻塞的 当容器中没有位置了就阻塞 直到有人从里面取走元素为止

print(q.get())
print(q.get())
print(q.get(block=True,timeout=3))# 默认是阻塞的 当容器中没有位置了就阻塞 直到有人存入元素为止

8.函数调用栈

def a():
    b()
 
def b():
    c()
    
def c():
    print('c')
    raise Exception    
a()   
posted @ 2019-07-03 18:37  海森t  阅读(47)  评论(0)    收藏  举报