zoukankan      html  css  js  c++  java
  • 学习总结(三十三)

    1.守护进程

              1)什么是守护进程

                      进程是一个正在运行的程序,守护进程也是一个进程,守护进程的意思就是一个进程保护另一个进程

              2)守护进程使用场景

                  子进程需要父进程才能完成的任务,例如迅雷下载,如果父进程迅雷,没有守护子进程就结束了,子进程就没有父进程的守护,子进程的下载任务就完成不了

     

    2.互斥锁

           1)什么是互斥锁

                   互斥锁就是互相排斥的锁,(一个资源被锁了,其他子进程就无法使用)

           2)为什么需要互斥锁

                  因为并发带来的资源竞争问题,当多个进程同时要操作一个资源将会导致数据错乱

            3)解决数据混乱的方法

                 1 . 使用join()可以解决数据混乱,但是会把并发任务变成了串行,虽然解决了数据错乱的问题,但是效率降低了,这样就没有开启子进程了

                 2. 原本多个进程之间是公平竞争,join执行的顺序就定死了,这不合理

                 3. 给公共资源加锁,互斥锁

            4)锁和join的区别

                  1. join是固定执行顺序,会造成父进程等待子进程,锁依然是公平竞争,谁先抢到谁先执行,父进程可以做其他的事情

                   2.  最主要的区别:join是把进程全部串行,锁可以任意代码一行也可以,可以自己调整粒度

      

    from multiprocessing import Process,Lock
    import time,random
    
    def task1(lock):
        # 要开始使用了 上锁
        lock.acquire()       #就等同于一个if判断
        print("hello iam jerry")
        time.sleep(random.randint(0, 2))
        print("gender is boy")
        time.sleep(random.randint(0, 2))
        print("age is  15")
        # 用完了就解锁
        lock.release()
    
    def task2(lock):
        lock.acquire()
        print("hello iam owen")
        time.sleep(random.randint(0,2))
        print("gender is girl")
        time.sleep(random.randint(0,2))
        print("age is  48")
        lock.release()
    
    def task3(lock):
        lock.acquire()
        print("hello iam jason")
        time.sleep(random.randint(0,2))
        print("gender is women")
        time.sleep(random.randint(0,2))
        print("age is  26")
        lock.release()
    
    if __name__ == '__main__':
        lock = Lock()
    
        p1 = Process(target=task1,args=(lock,))
        p2 = Process(target=task2,args=(lock,))
        p3 = Process(target=task3,args=(lock,))
    
        p1.start()
        # p1.join()
    
        p2.start()
        # p2.join()
    
        p3.start()
        # p3.join()
    
        # print("故事结束!")
        
    # 锁的伪代码实现 
    
    # if my_lock == False:
    #     my_lock = True
    #	  #被锁住的代码
    	  my_lock = False 解锁
    

      

    3.IPC进程间通讯

                1.什么是IPC进程间通讯

                         通讯指的就是交换数据,进程之间相互隔离,当一个进程想要把数据给另一个进程,就要考虑IPC进程间通讯

                2.IPC通讯和socket对比

                         1)IPC通讯  

                                管道:上只能单向通讯

                               文件:在硬盘上创建共享文件

                                           缺点:速度慢

                                          优点: 数据量几乎没有限制

                         2)socket通讯

                                 编程复杂度较高

                                 共享内存:必须由操作系统来分配

                                  缺点:数据量不能太大

                                  优点:速度快

    4.Manager类

                   Manager所创建出来的数据结构,具备进程共享的特点, 需要强调的是 Manager创建的一些数据结构是不带锁的 可能会出现问题

           

    from multiprocessing import Process,Manager,Lock
    import time
    
    
    def task(data,l):
        l.acquire()
        num = data["num"] #
        time.sleep(0.1)
        data["num"] = num - 1
        l.release()
    
    if __name__ == '__main__':
        # 让Manager开启一个共享的字典
        m = Manager()
        data = m.dict({"num":10})
    
        l = Lock()
    
        for i in range(10):
            p = Process(target=task,args=(data,l))
            p.start()
    
        time.sleep(2)
        print(data)
    

      

    5.Queue队列

           1)什么是队列

                      队列是一种特殊的数据结构先存储的先取出,就像排队一样,先进先出 

                      注:堆栈是先存储后取出,就像衣柜一样

        

    from multiprocessing import Queue
    # 创建队列  不指定maxsize 则没有数量限制
    q = Queue(3)
    # 存储元素
    # q.put("abc")
    # q.put("hhh")
    # q.put("kkk")
    
    # print(q.get())
    # q.put("ooo")    # 如果容量已经满了,在调用put时将进入阻塞状态 直到有人从队列中拿走数据有空位置 才会继续执行
    
    #取出元素
    # print(q.get())# 如果队列已经空了,在调用get时将进入阻塞状态 直到有人从存储了新的数据到队列中 才会继续
    
    # print(q.get())
    # print(q.get())
    
    
    #block 表示是否阻塞 默认是阻塞的   # 当设置为False 并且队列为空时 抛出异常
    q.get(block=True,timeout=2)
    # block 表示是否阻塞 默认是阻塞的   # 当设置为False 并且队列满了时 抛出异常
    # q.put("123",block=False,)
    # timeout 表示阻塞的超时时间 ,超过时间还是没有值或还是没位置则抛出异常  仅在block为True有效
    

      

    6.生产者消费者模型

         1)生产者和消费者模型是什么

                   模型就是解决某个问题套路

                    产生数据的一方称之为生产者

                    处理数据的一方称之为消费者

           2)生产者和消费者解决什么问题

                  处理生产者和消费,处理速度不平衡,一方快一方慢,导致一方需要等待另一方

                 将双方分开来,一方专门负责生产,一方负责处理

                生产者完成后放入容器,消费者从容器中取出数据,这样就解决了双方法能力不平衡的问题,做的快的一方而可以继续做,不需要等待另一方

    def eat(q):
        for i in range(10):
            # 要消费
            rose = q.get()
            time.sleep(random.randint(0, 2))
            print(rose,"吃完了!")
    
    # 生产任务
    def make_rose(q):
        for i in range(10):
            # 再生产
            time.sleep(random.randint(0, 2))
            print("第%s盘青椒肉丝制作完成!" % i)
            rose = "第%s盘青椒肉丝" % i
            # 将生成完成的数据放入队列中
            q.put(rose)
    
    if __name__ == '__main__':
        # 创建一个共享队列
        q = Queue()
        make_p = Process(target=make_rose,args=(q,))
        eat_p =  Process(target=eat,args=(q,))
    
    
        make_p.start()
        eat_p.start()
    

      

  • 相关阅读:
    Unity动态批处理和静态批处理学习
    Mac下Unity使用Jenkins自动化打包
    Mac 环境环境下安装Git与使用(码云)
    MySQL: 6、MySQL语句
    MySQL: 5、MySQL索引、视图、存储过程
    MySQL: 4、多表、外键、数据库设计
    MySQL: 3、SQL语言 ②约束、事务
    MySQL: 2、SQL语言 ①概念、分类
    MySQL: 1、MySQL基础
    Mac 系统下如何显示和隐藏文件
  • 原文地址:https://www.cnblogs.com/xzcvblogs/p/10969723.html
Copyright © 2011-2022 走看看