zoukankan      html  css  js  c++  java
  • 并发编程知识点汇总

    计算机输入和输出的过程就称为“IO”(“input”、“output”),比如 程序一旦执行,就由操作系统决定cpu和Io的优化算法,不能人为干预,比如 input、time.sleep()、读文件、写文件都是Io
    比如读文件,就是从硬盘中读取到内存中,此时和CPU还没发生关系


    操作系统的三种类型:(我们现在常用的操作系统是具有多种操作特征的操作系统,或者具备以下两种或以上)
    多道批处理系统:
    (多个程序执行,遇见IO的话CPU就切换任务)
    分时系统:
    (多个程序执行,按时间轮流执行,时间到的话CPU就切换任务)
    实时系统:
    (多个程序执行,一直等着响应,CPU不切换,一般用于军事、情报、银行等等)




    硬盘➡️内存➡️CPU 硬盘读取到内存是机械爪在工作,CPU是从内存总读取数据然后

    ,所以以上两者工作的时候互不影响。


    两个程序同时运行的时候,在内存中各自占领一块儿互不干涉的内存空间,而分配内存空间这件事儿是操作系统干的,
    两个程序同时运行的时候:
    从宏观上看是并行的(看着确实是两个程序在同时运行)
    从微观上看是串行的(实际上还是轮流使用CPU)
     



    所谓并发就是有多个进程 在同一时刻执行同一段代码

    子进程中不能有input,因为主进程与子进程是两个单独的进程

    多进程实现并发效果
    开启多进程有两种方法
    人为和内存打交道或者硬盘和内存打交道,不涉及到cpu计算的就是一个IO,
    例如input或者从硬盘读取文件都是一个IO

    操作系统的作用:
    (1)隐藏硬件接口,提供良好的抽象接口
    (2)管理、调度进程,将多个进程对硬件的竞争变的有序
    运行中的程序就是进程
    程序是一个没有生命的实体,只有运行它的时候才会成为一个活动的实体,我们称之为进程


    并行:比如两个CPU执行两个程序,这时候进程之间就是并行
    并发:比如一个CPU执行两个程序,这时候进程之间就是并发的,从宏观上看是同时执行的,从微观上看是轮流执行的
    同步:比如去银行排队,一直等着就是同步,只能等着,其他什么也不能干
    异步:比如去银行排队,拿着排队的号码,轮到我的时候银行柜台的人来喊我,而在等待的过程中我还能去干其他的事情
    阻塞:time.sleep、input等就是阻塞
    非阻塞:没有time.sleep、input等就是非阻塞
    同步阻塞:效率最低,就像上面的去银行排队,等着的时候什么都不干
    异步阻塞:就像上面银行排队拿了一张小纸条,等号的的时候可以干一些其他的事情
    同步非阻塞:一边排队等号,一边打电话,还要在打电话与看看排队到自己没来回切换,效率是低下的
    异步非阻塞:效率高,专心打电话,该自己办业务的时候有银行的人员通知自己办理
    进程与子进程:比如运行pycharm是一个父进程,这时候在pycharm里面run文件,就是一个个的子进程,关系看下图


    这个时候创建的子进程和下面的print不一定谁先执行,因为开启一个子进程,是就绪状态,等到时间片轮到这个进程的时候,这个进程才会启动

    单进程:
    多进程:


    进程都有一个进程号,就是PID(P是Process,进程的意思)可以在任务管理器中查看
    进程的生命周期如下图:


     
    join():确保上面进程执行完毕再执行下面的代码,也就是使异步变为同步
    多个进程之间的数据是完全隔离的,就算父进程与子进程之间的数据也是完全隔离的


    进程三状态图







    开启进程的第二种方式:




    进程与进程之间的数据是完全隔离的


    多进程中子进程常用属性和方法:
    start():开始一个子进程
    join():感知一个子进程的结束
    terminate():结束一个进程
    is_alive():检查一个进程是否结束
    name:查看进程名
    daemon:为True的时候,表示新的子进程是一个守护进程
    守护进程:在进程start之前设置daemon为True
    随着主进程的代码执行完毕而结束,这个子进程称之为守护进程,而不是随着主进程的结束而结束
         比如一个主进程有两个子进程,一个守护进程,一个平常的子进程,当主进程代码结束,而那个平常的子进程还没结束,这个时候守护进程也会结束,因为守护进程是随着
    主进程的代码执行完毕而结束,而不是随着主进程的结束而结束


    △:当terminate一个进程就是向操作系统发送一个关闭进程的请求 此时如果立即is_alive进程极有可能会显示为True,因为知识向操作系统发送关闭子进程的请求,操作系统可能不会立即执行,这中间还有一点儿缓冲时间
    因为结束一个进程是向操作系统发送一个结束请求,系统不会立即反应过来,需要一个操作系统响应的过程

    进程锁: from multiprocessing import Lock
    lock = Lock()
    需要加锁的代码前面:lock.acquire() #拿钥匙
    需要加锁的代码前面:lock.release() #还钥匙
    涉及到修改数据的代码操作都需要加锁


    pycharm中开启子进程不能涉及到输入,因为开启子进程就相当于又开辟了一块儿新的空间,写聊天系统的时候server端也不会涉及到输入,因为最终聊天是客户端与客户端在聊天,而server端只是一个中间平台。



    信号量: from multiprocessing import Semaphore
    用途用法和进程锁一样,进程锁是控制一个进程工作,信号量是控制多个进程工作

    事件:
    from multiprocessing import Event
    e = Event() #创建一个事件
    print(e.is_set()) # 查看这个事件的阻塞状态,默认False
    e.set() # 将这个事件的阻塞状态改为True
    print(e.is_set())
    e.wait() # 根据is_set()的值决定是否阻塞 True为不阻塞,False为阻塞
    e.clear() # 将这个事件的阻塞状态改为False
    print(e.is_set())



    进程间的通信: IPC(inter-process-commmunication)



    队列:先进先出


    from multiprocessing import Queue
    q = Queue(3)#创建队列,参数为可放入的数量
    q.put(1)#放入数据
    q.put(2)
    q.put(3)
    print(q.get())#取数据,如果为空就阻塞
    print(q.full())#查看队列是否满了
    print(q.get())#取查看队列是否有空位
    try:
    print(q.get_nowait())#取数据,如果为空不阻塞,所以可用捕捉异常,另行处理
    except:
    print("没值了")

    生产者消费者模型,以队列为基础



    from multiprocessing import Process, JoinableQueue
    import time, random
    def produce(name, food, q):
        for i in range(1, 11):
            time.sleep(random.random())
            print("{}生产了{}{}".format(name, food, i))
            q.put("{}{}".format(food, i))
        q.join()
    
    def consume(name, q):
        while 1:
            time.sleep(random.random())
            print("{}消费了{}".format(name, q.get()))
            q.task_done()
    
    
    if __name__ == '__main__':
        q = JoinableQueue()
        p1 = Process(target=produce, args=("小黑", "包子", q))
        p1.start()
        p2 = Process(target=produce, args=("小白", "馒头", q))
        p2.start()
        c1 = Process(target=consume, args=("alex", q))
        c1.daemon = True
        c1.start()
        c2 = Process(target=consume, args=("egon", q))
        c2.daemon = True
        c2.start()
        p1.join()
        p2.join()
    View Code
    
    
    
     
  • 相关阅读:
    js 数据类型的转换
    js数组学习方法汇总
    跳转页面的方法总结
    今天用js做拉一个时钟
    今天用js做拉一个时钟
    js中字符的比较
    1005 继续(3n+1)猜想 (25分)
    1002 写出这个数
    日期差值
    1040 有几个PAT (25分)
  • 原文地址:https://www.cnblogs.com/QimiSun/p/10012399.html
Copyright © 2011-2022 走看看