zoukankan      html  css  js  c++  java
  • 并发编程(初学)

    并发编程(初学)

    一、操作系统的发展史

    1、第一代计算机:真空管和穿孔卡片

    • 特点:没有操作系统的概念,所有的程序设计都是直接操控硬件
    • 优点:程序员在申请的时间段内独享整个资源,可以即时地调试自己的程序
    • 缺点:浪费计算机资源,一个时间段内只有一个人用

    2、第二代计算机:晶体管和批处理系统

    • 特点:有了操作系统的概念,有了程序设计语言:FORTRAN语言或汇编语言,写到纸上,然后穿孔打成卡片,再讲卡片盒带到输入室,交给操作员,然后喝着咖啡等待输出接口

    • 优点:批处理,节省了机时和资源

    • 缺点:1.整个流程需要人参与控制,将磁带搬来搬去

        	 2.计算的过程仍然是顺序计算-》串行
      

      ​ 3.程序员原来独享一段时间的计算机,现在必须被统一规划到一批作业中,等待结果和重新调试的过程都需要 等同批次的其他程序都运作完才可以(这极大的影响了程序的开发效率,无法及时调试程序)

    3、第三代计算机:集成电路复用和多道程序设计

    • 多道技术:

      ​ 1、产生背景:针对单核,实现并发

      (现在的主机一般是多核,那么每个核都会利用多道技术。有4个cpu,运行于cpu1的某个程序遇到io阻塞,会等到io结束再重新调度,会被调度到4个cpu中的任意一个,具体由操作系统调度算法决定。

      ​ 2、空间复用:共用一个内存条,每一个进程都有自己独立的内存空间,互不干扰,物理级别的隔离

      ​ 3、时间复用:共用一个cpu,IO的时候占用时间过长

    4、第四代计算机:个人计算机

    二、必备的理论基础

    1、操作系统的作用:

    ​ 1、隐藏丑陋复杂的硬件接口,提供良好的抽象接口

    ​ 2、管理、调度进程,并且将多个进程对硬件的竞争变得有序

    2、cpu切换:

    ​ 遇到io切换,占用cpu时间过长也切换,核心在于切之前将进程的状态保存下来,这样才能保证下次切换回来时,能基于上次切走的位置继续运行

    三、进程

    1. 进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。
    2. 进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时(操作系统执行之),它才能成为一个活动的实体,我们称其为进程。

    进程是操作系统中最基本、重要的概念。是多道程序系统出现后,为了刻画系统内部出现的动态情况,描述系统内部各道程序的活动规律引进的一个概念,所有多道程序设计操作系统都建立在进程的基础上。

    四、创建并开启子进程的两种方式

    4.1 方式一

    #单个进程
    from multiprocessing import Process
    import time
    
    def Text():
        print('我是一个子进程')
        print('我的进程开始了')
        time.sleep(2)
        print('我的进程结束了')
    
    
    if __name__ == '__main__':  #windows下必须要写这一句,不然会报错
        p = Process(target = Text)   #实例化产生一个对象
        p.start()   # 告诉操作系统我要开子进程,告诉完了这行代码就算执行完了,接着往下走,具体操作系统什么时候开子,开多长时间跟你没关系
        time.sleep(5)
        print('我是主进程,我要结束了')
    #多个进程
    
    #多个进程
    from multiprocessing import Process
    import time
    
    def Text(x):
        print(f'我是子进程{x}')
        print(f'{x}的进程开始了')
        time.sleep(2)
        print(f'{x}的进程结束了')
    
    
    if __name__ == '__main__':  #windows下必须要写这一句,不然会报错
        p1 = Process(target = Text,args=('yjy',))   #实例化产生一个对象  子进程1
        p2 = Process(target = Text,args=('ypp',))   #实例化产生一个对象  子进程2
        p1.start()   # 告诉操作系统我要开子进程,告诉完了这行代码就算执行完了,接着往下走,具体操作系统什么时候开子,开多长时间跟你没关系
        p2.start()   # 告诉操作系统我要开子进程,告诉完了这行代码就算执行完了,接着往下走,具体操作系统什么时候开子,开多长时间跟你没关系
        time.sleep(5)
        print('我是主进程,我要结束了')
    

    4.2 方式二

    from  multiprocessing import Process
    import time
    
    class Text(Process):  #定义一个类,让他继承Process
        def __init__(self,name):    #重写__init__
            super().__init__()   #继承父类的__init__方法
            self.name = name
    
        def run(self):  #定义一个函数
            print(f'子进程的姓名为{self.name},子进程开始')
            time.sleep(2)
            print(f'{self.name}进程结束')
    
    
    if __name__ == '__main__':
        p = Text('yjy')
        p.start()  #通知操作系统子进程开始
        print('主进程结束')
    

    五、验证进程的内存空间隔离

    from multiprocessing import Process
    import time
    
    x = 0  #定义一个变量x
    def Check():
        global x
        x = 100
        print(f'子进程的x:{x}')
    
    
    if __name__ == '__main__':
        p = Process(target=Check)
        p.start()
        print(f'父进程的x:{x}')
       
    

    父进程的x:0
    子进程的x:100

    父进程的x和子进程的x不是一个值,说明他们两个进程互不影响!

    六、僵尸进程和孤儿进程

    僵尸进程(有害):当子进程结束的时候,不会将所有内容都释放掉,他会留下自己的pid(类似身份证号码)供父进程来查看,此所谓进程死了没死干净,这就是僵尸进程,他会等待父进程最后把他处理掉

    孤儿进程(无害):一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

  • 相关阅读:
    查看Java中每个数据类型所占的位数,和表示数值的范围,并得出结论。
    同名变量的屏蔽原则
    反码,补码,原码
    机器学习概念性知识总结
    图的最短路径问题
    System Design 笔记及代码(系统设计)
    2016网易游戏实习算法题解(今年找暑期实习的时候参加的)
    Google java style
    18.1---不用加号的加法(CC150)
    Java模板模式(template)
  • 原文地址:https://www.cnblogs.com/zhuangyl23/p/11509114.html
Copyright © 2011-2022 走看看