• 并发编程(一)


    并发编程(上)

    操作系统发展史

    操作系统的发展史

    穿孔卡片:

    一个计算机机房,一次只能被一个卡片使用.

    缺点:CPU利用率最低.

    联机批处理系统:

    支持多用户去使用一个计算机机房.

    脱机批处理系统:

    高速磁盘:提高文件的读取速度

    优点:提高CPU的利用率

    进程基础

    进程是对正在运行程序的一个抽象.

    1. 操作系统的作用

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

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

    2. 多道技术(基于单核情况下研究):

      单道:多个使用使用CPU时是串行.

      多道技术:

      空间上的复用-->一个CPU可以提供给多个用户去使用.

      时间上的复用-->切换 + 保存状态

      IO操作:input();print();time.sleep(3)

      1 若CPU遇到IO操作,会立即将当前执行程序CPU使用权断开

      2 若一个程序使用CPU的时间过长,会立即将当前执行程序CPU使用权断开.

      特点:程序的执行率降低

    进程调度
    1. 先来先服务调度算法

      a,b程序,若A先来,先占用CPU;缺点是程序A先使用,程序B必须等待程序A使用CPU结束后才能使用.

    2. 短作业优先调度算法

      a,b程序,谁的用时短,先优先调度使用CPU;缺点是若程序A使用时间长,有N个程序使用时间短.必须等待所有短的程序结束后才能使用.

    3. 时间片轮转法

      CPU执行的时间一秒钟,加载N个程序,将要一秒等分成N个时间片.

    4. 多级反馈队列

      将执行优先分为多层级别.

      一级;优先级最高

      二级;优先级第二,依次类推

    并发与并行

    ==并行==

    并行是指两者同时执行,比如赛跑,两个人都在不停的往前跑;(资源够用,比如三个线程,四核CPU)

    ==并发==

    并发是指资源有限的情况下,两者交替轮流使用资源,比如一段路(单核CPU资源)同时只能过一个人,A走一段后,让给B,B用完继续给A,交替使用,目的是提高效率.

    同步异步阻塞非阻塞
    1. 同步

      若有两个任务需要提交,在提交第一个任务时,必须等待该任务执行结束后,才能继续提交并执行第二个任务

    2. 异步

      若两个任务需要提交,在提交第一个任务时,不需要原地等待,立即可以提交并执行第二个任务

    3. 阻塞

      阻塞态,遇到IO一定会阻塞(凡是遇到IO操作的进程,都会进入阻塞态.若IO结束,必须重新进入就绪态.

    4. 非阻塞

      就绪态(所有进程创建时都会进入就绪态,准备调度)

      运行态(调度后的进程,进入运行态)

    创建进程的两种方式

    ==UNIX和Windows创建进程==

    1. 在UNIX中该系统调用是:fork,fork会创建一个与父进程一模一样的副本,二者有相同的映像,同样的环境字符串和同样的打开文件(在shell解释器进程中,执行一个命令就会创建一个子进程)
    2. 在Windows中该系统调用是: createprocess, createprocess既处理进程的创建.也负责八正确的程序装入新进程.

    关于创建子进程,UNIX和Windows:

    1. 相同的是: 进程创建后,父进程和子进程有各自不同的地址空间,(多道技术要求物理层面实现进程之间内存的隔离),任何一个进程在其他地址空间中的修改都不会影响到另外一个进程.
    2. 不同的是:在UNIX中,子进程的初始地址空间是父进程的一个副本,提示:子进程和父进程是可以有只读的共享内存区的,但是对于Windows系统来说,从一开始父进程与子进程的地址空间就是不同的.

    进程的结束:1.正常退出;2.出错退出;3.严重错误;4.被其他进程杀死

    开启多进程(multiprocess.process)

    multiprocess模块

    仔细来说,multiprocess不是一个模块,而是python中一个操作,管理进程的包.由于提供的子模块非常的多,为了方便归类记忆,可以分为四个部分:创建进程部分,进程同步部分,进程池部分,进程之间数据共享.

    1. multiprocess.process模块

      process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建.

    2. process模块

      process([group [,target [,name [,args [,kwargs]]]]])

      由上面类实例化得到的对象,表示一个子进程的任务(尚未启动)

      强调:

      需要使用关键字的方式来指定参数

      args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号

      参数介绍:

      1. group参数未使用,值始终为none
      1. target表示调用对象,即子进程要执行的任务
      1. args表示第哦啊用对象的位置参数元组,args=(q,2,'egon').
      2. kwargs表示调用对象的字典,kwargs={'name':'egon','age':19}
      3. name为子进程的名称

      方法介绍:

      1. p.start:启动进程,并调用该子进程的p.run()
      2. p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法
      3. p.terminate():强制终止进程P,不会进行任何清理操作,如果P还保存了一个锁那么也将不会被释放,进而导致死锁
      4. p.is_alive:如果P仍然运行,返回true。
      5. p.join([timeout]):主线程等待P终止(强调:是主线程处于等的状态,而P是出于运行的状态)。timeout是可以选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程。

      属性介绍:

      1. p.daemon:默认值为false,如果设为true,代表P为后台运行的守护进程,当P的父进程终止时,P也随之终止,并且设定为true后,P不能创建自己的新进程,必须在p.start()之前设置。

      2. p.name:进程的名称

      3. p.pid:进程的pid。

      在Windows中使用process注意事项

      在Windows操作系统中,由于没有fork(Linux操作系统中创建进程的机制),在创建子进程的时候会自己动import启动它的这个文件,而在import的时候又执行了整个文件。因此如果将process()直接写在文件中就会无线递归创建子进程报错,所以必须把创建子进程的部分使用if__name___=='__main__'判断保护起来,import的时候,就不会递归运行了。

    3. 使用process模块创建进程

      在一个python进程中开启子进程start方法和并发效果

    4. 守护进程

      会随着主进程的结束而结束

      主进程创建守护进程

      1. 守护进程会在主进程代码执行结束后九终止、
      2. 守护进程内无法再开启子进程,否则抛出异常
    5. socket并发实例

      使用多进程实现socket聊天并发送——server端

      使用多进程实现socket聊天并发——client端

    6. 多进程中其他方法

      进程对象的其他方法:terminate和is_alive

      进程对象的其他属性:pid和name

    进程同步(multiprocess.lock)

    通过学习了异步,让多个任务可以同时在几个进程中并发处理,他们之间的运行没有顺序,一旦开启也不受我们控制。尽管并发编程让我们能更加充分的利用io资源,但是也给我们带来了新的问题:当多个进程使用同一份数据资源的时候,就会引发数据安全或顺序混乱问题。

    1. 多进程抢占输出资源

      import os 
      import time
      import random
      from multiprocessing import process
      
      def wrok(n):
          print('%s: %s is runing' %(n,os.getpid()))
          time,sleep(random.random)
       print('%s: %s is done' %(n,os.getpid()))
      
      if __name__ == '__main__':
          for i in range(3):
              p=process(target=work,args=(i,))
              p.start
    2. 使用锁维护执行顺序

      import os 
      import time 
      import random
      from multiprocess import process,lock
      
      def work(lock,n):
          lock.acquire()
          print('%s: %s runing' %(n,os.getpid()))
          time.sleep(random.random())
          print('%s: %s is done' %(n,os.getpid()))
          lock.release()
      if __name__=='__main__':
          lock=lock()
          for i in range()
           p=process(targs=work,args=(lock,i))
              p.start()

      上述这种情况虽然使用加锁的形式实现了顺序的执行,但是程序又重新变成串行了,这样确实会浪费了时间,却保证了数据的安全。

    3. 使用锁来保证数据安全

      加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以修改,即串行的修改,没错,速度是慢了,但牺牲了速度却保证了数据安全。

      虽然可以使用文件共享数据实现进程间的通信,但问题是:

      1. 效率低(共享数据基于文件,而文件是硬盘上的数据)
      2. 需要自己加锁处理

      因此我们最好找寻一种解决方案能够兼顾:

      1. 效率高(多个进程共享一块内存的数据)
      2. 帮我们处理好加锁问题。这就是mutiprocessing模块为我们提供的基于消息的ipc通信机制:队列和管道。

      队列和管道都是将数据存放于内存中,队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来,我们应该尽量避免使用共享数据,尽可能使用消息传递和队列,避免处理复杂的同步和锁问题,而且在进程数目增多时,往往可以获得更好的可获展性。

    我把月亮戳到天上 天就是我的 我把脚踩入地里 地就是我的 我亲吻你 你就是我的
  • 相关阅读:
    SAP OPEN UI5 Step 8: Translatable Texts
    SAP OPEN UI5 Step7 JSON Model
    SAP OPEN UI5 Step6 Modules
    SAP OPEN UI5 Step5 Controllers
    SAP OPEN UI5 Step4 Xml View
    SAP OPEN UI5 Step3 Controls
    SAP OPEN UI5 Step2 Bootstrap
    SAP OPEN UI5 Step1 环境安装和hello world
    2021php最新composer的使用攻略
    Php使用gzdeflate和ZLIB_ENCODING_DEFLATE结果gzinflate报data error
  • 原文地址:https://www.cnblogs.com/zhulipeng-1998/p/12863936.html
Copyright © 2020-2023  润新知