• doraemon的python 守护进程和Process


    ### 9.4 Process模块    进程
    
    ```python
    from multiprocess import Process
    p = Process(target=函数名,args=(参数1,))
    
    1.如何创建一个进程对象
        对象和进程之间的关系:
        a.进程对象和进程并没有直接的关系
        b.只是存储了一些和进程相关的内容
        c.此时此刻,操作系统还没有接收到创建进程的指令
        
    2.如何开启一个进程
        通过p.start()开启一个进程,这个方法相当于给操作系统一个开启指令指令
        start方法的异步非阻塞的特点:
            a.在执行这个方法的时候,我们既不等待进程开启,也不等待操作系统给我们的想要
            b.这里只是负责同志操作系统去开启一个进程
            开启一个子进程之后,主进程和子进程的代码完全异步
            
    3.父进程和子进程之间的关系
        a.父进程会等待子进程结束之后才结束
        b.是为了挥手子进程的资源
        
    4.不同操作系统中进程开启的方式
        windows 通过(模块导入)再一次执行父进程文件中的代码来获取父进程中的数据
        所以只要是不希望被子进程执行的代码,就写在if __name__ == '__main__'下
         因为在进行导入的时候父进程文件中的__name__ != '__main__'
         linux/ios
         正常的写就可以,没有if __name__ == '__main__'这件事情了
    5.如何确认一个子进程执行完毕
            join方法
            开启了多个子进程,等待所有子进程结束
            
    ```
    
    #### 9.4.1 守护进程
    
    ```python
    def son1(a,b):
        while True:
            print('is alive')
            time.sleep(0.5)
    
    def son2():
        for i in range(5):
            print('in son2')
            time.sleep(1)
           
    if __name__ == "__main__":
        p = PROcess(target=son1,args=(1,2))
        p.daemon = True
        p.start()
        p2 = Process(target=son2)
        p2.start()
        time.sleep(2)
        
    #守护进程是随着主进程的代码结束而结束
        生产者消费者模型的时候
        守护线程做对比的时候
    #所有子进程都必须在主进程结束之前结束,由主进程挥手资源
    ```
    
    ```python
    # 有一个参数可以把一个子进程设置为一个守护进程
    import time
    from multiprocessing import Process
    
    def son1():
        while True:
            print('is alive')
            time.sleep(0.5)
    
    if __name__ == '__main__':
        p = Process(target=son1)
        p.start()      # 异步 非阻塞
        print(p.is_alive())
        time.sleep(1)
        p.terminate()   # 异步的 非阻塞
        print(p.is_alive())   # 进程还活着 因为操作系统还没来得及关闭进程
        time.sleep(0.01)
        print(p.is_alive())   # 操作系统已经响应了我们要关闭进程的需求,再去检测的时候,得到的结果是进程已经结束了
    
    # 什么是异步非阻塞?
        # terminate
    
    ```
    
    #### 9.4.2 面向对象方式的守护进程
    
    #### 9.4.3 Process类的总结
    
    ```python
    # Process类
    # 开启进程的方式
        # 面向函数
            # def 函数名:要在子进程中执行的代码
            # p = Process(target= 函数名,args=(参数1,))
    
        #面向对象
            #class 类名(Process):
                #def __init__(self,参数1,参数2):
                    #self.a = 参数1
                    #self.b = 参数2
                    #super().__init__()
                #def run(self):
                    #需要在紫禁城中执行的代码
            #p = 类名(参数1,参数2)
            #p.start()   异步非阻塞
            #p.terminate()   异步非阻塞
            #p.join()    同步阻塞
            #p.isalive()    获取当前进程状态
            #daemon = True 设置为守护进程,守护进程会在主进程代码结束后结束
    ```
    
    #### 
    
    ### 9.5 锁
    
    #### 9.5.1 什么时候需要用锁
    
    - 如果在一个并发条件下,涉及的某部分内容
      - 是需要修改一些所有进程共享的数据资源
      - 需要枷锁类维持数据的安全
    - 在数据安全的基础上,才考虑效率问题
    - 同步存在的意义
      - 数据安全
    
    #### 9.5.2 锁在代码中的应用顺序
    
    - 在主进程中实例化lock = Lock()
    - 把这把锁传递给子进程
    - 在子进程中 对需要枷锁的代码进行with lock:
      - with lock 相当于lock.acquire()和lock.release()
    - 在主进程需要加锁的场景:
      - 共享数据资源(文件、数据等)
      - 对资源进行修改删除操作
    - 加锁之后能保证数据的安全性 但同时也降低了程序的执行效率
    
    ```python
    import time
    import json
    from multiprocessing import Process,Lock
    
    def search_ticket(user):
        with open('ticket_count') as f:
            dic = json.load(f)
            print('%s查询结果  : %s张余票'%(user,dic['count']))
    
    def buy_ticket(user,lock):
        # with lock:
        # lock.acquire()   # 给这段代码加上一把锁
            time.sleep(0.02)
            with open('ticket_count') as f:
                dic = json.load(f)
            if dic['count'] > 0:
                print('%s买到票了'%(user))
                dic['count'] -= 1
            else:
                print('%s没买到票' % (user))
            time.sleep(0.02)
            with open('ticket_count','w') as f:
                json.dump(dic,f)
        # lock.release()   # 给这段代码解锁
    
    def task(user, lock):
        search_ticket(user)
        with lock:
            buy_ticket(user, lock)
    
    if __name__ == '__main__':
        lock = Lock()
        for i in range(10):
            p = Process(target=task,args=('user%s'%i,lock))
            p.start()
    ```
    
    #### 9.5.3 进程之间的通信(IPC)
    
    ```python
    # 通信
     #进程之间的通信 - IPC(inter process communication)
     from multiprocessing import Queue,Process
     # 先进先出
     def func(exp,q):
         ret = eval(exp)
         q.put({ret,2,3})
         q.put(ret*2)
         q.put(ret*4)
    
     if __name__ == '__main__':
         q = Queue()
         Process(target=func,args=('1+2+3',q)).start()
         print(q.get())
         print(q.get())#     print(q.get())
    
    # Queue基于 天生就是数据安全的
        # 文件家族的socket pickle lock
    # pipe 管道(不安全的) = 文件家族的socket pickle
    # 队列 = 管道 + 锁
    
    ```
  • 相关阅读:
    [HNOI2008] Cards
    loj #136
    a problem
    dp * 3
    STL
    套题1
    luogu 4211
    loj #2319
    loj #2316
    luogu 1144
  • 原文地址:https://www.cnblogs.com/doraemon548542/p/11421654.html
Copyright © 2020-2023  润新知