疑点:
    Process.run():启动一个子进程,会执行在构建函数中传递地方法。(不理解) Process.terminate():强制终止子进程,不会进行资源清理。(为什么不清理?意义所在?)
    Pipe模块是对进程管道通信机制的封装,在这种通信机制中,数据只能向一个方向流动(部分系统支持双向管道)
    问题:管道是否支持双向是由系统决定的?不是模块自身的功能?

    理解并发
    1 在计算机的概念里,是指程序在交替执行。
    2 负责程序执行的硬件是CPU,在只有一个CPU核心的情况下,很难做到多个程序同时执行,
    所以就需要程序交替着执行,在一段时间内轮流执行,这就叫程序的并发执行。
    理解并行
    1 存在多个CPU时,多个程序就可以同时执行,每个CPU执行一个程序。
    2 CPU与程序之间的分配、调度是由操作系统来负责的。
    并发与并行的关系
    1 并发是指交替执行,交替的时间越短时,就等同于同时执行,这是并发就变成并行。
    2 所以可以将并行视为并发的一种特殊情况,将并行视为并发的子集。
    理解进程(process)
    进入任务管理器
    windows中,在命令行中输入taskmgr进入
    linux中,在命令行中输入top进入
    1 进程是动态的概念,程序是静态的,程序在执行的时候就变成动态的,这个状态就是进程。
    2 例如平常使用的APP,是一个程序。当我们点击app,app运行时,就变成了一个进程。
    3 程序是静态的文件,而进程是动态的执行实体。为了执行这个程序,操作系统必须为该进程
    分配CPU、内存、磁盘等系统资源。
    ** GPU是在硬件显卡中的图像处理器,是高度并行化的硬件架构。
    4 进程是操作系统进行资源分配的基本单位。
    5 操作系统是进程的容器,里面运行着各种各样的进程,占用有限的CPU、内存、磁盘等资源,
    所以在软件开发时,需要考虑两个问题:如何减少程序对系统资源的占用?如何优化执行性能?

    进程的地址空间
    进程占用内存的大小就是地址空间
    1 地址空间分为虚拟的地址空间和物理地址空间,进程的物理地址空间对应的是进程实际占用的这块
    物理内存。
    2 进程地址空间的内存布局,主要分为四个部分:代码段、数据段、堆区、栈区。
    3 通常说的地址空间是指虚拟地址空间,操作系统在实际实现中将内存与磁盘抽象为虚拟内存,
    并为进程提供了一层抽象,使得每个进程都在独占地使用这块虚拟内存。这块虚拟内存即为
    进程的虚拟地址空间。在32位系统中,虚拟空间为2的32次方字节,也就是4GB.
    进程的状态
    1 运行态
    2 休眠态
    3 就绪态
    上下文的状态信息是保存在内存中的。
    进程的父子关系
    不会继承所有的,会继承常用的。例如文件的打开
    1 A进程创建了B进程,A就是B的父进程,B是A的子进程.
    2 子进程会继承父进程的部分资源,比如在Unix系统中,子进程继承了父进程的环境变量、工作目录、堆栈等。
    守护进程:daemon
    直接和用户交互的就是前台进程,一些服务进程是后台进程。
    1 守护进程是运行在后台的一类特殊进程。用于执行特定的系统任务,通常在系统引导或在需要的时候才启动,
    一直运行直到系统关闭。守护进程不受终端控制,周期性地处理某种任务或等待处理某些发生的事情。
    2 守护进程是后台进程,与后台进程相对的是前台进程,前台进程与用户交互,是用户当前正在使用的进程。
    前台与后台的进程可以相互转化。
    3 在Linux系统中执行命令时,在末尾加一个&符号,可以让命令在后台执行,通过nohup命令可以让进程以守护
    进程的方式执行,语法为:nohup command &。
    4 执行fg命令,可以将后台进程调至前台执行。
    5 对于当前正在执行的前台进程,按下键盘的CTRL+Z键,可以将其调至后台并挂起。
    6 执行bg命令以后恢复被挂起的后台进程,执行jobs命令可以查看所有的运行于后台的进程。
    进程间的通信
    数据交互
    1 进程间的通信,本质是进行数据的传输。
    2 进程间的通信可以通过文件方式来实现。A进程往文件中写入数据,B进程再从文件中读出数据。
    3 除了文件,系统还提供了其它的进程通信机制,比如共享内存、信号、套接字等
    共享内存是内存中的一块共享空间,通信效率比文件方式高。
    进程间的同步
    临界区(加锁、解锁的边界)、共享资源
    1 进程同步是指多个进程在进行协同工作或数据共享的过程中可能会发生冲突,这时引入了一些列
    机制来对进程间的操作进行协调和制约。
    2 如果系统只存在一个进程,或系统中的进程完全孤立存在,那就无需同步。之所以同步,是因为
    多个进程在并发地使用共享资源,或者需要协同完成同一个任务。
    3 windows和Unix系统都提供了进程间的同步机制,比如互斥锁和信号量。
    信号量也是一种锁机制。
    Linux命令行中进程常用指令
    1 top:动态实时显示系统资源和进程
    2 ps:用来列出当前系统中的进程状态信息。
    常用命令选项:①-e 显示所有进程,②-a 显示当前终端所有进程
    ③-f 显示进程间的关系,④-u 显示进程的用户信息
    3 kill:向进程发送信号。kill -s pid。s表示信号编号或者信号名。
    例如发送SIGKILL信号杀死进程1314,kill -9 1314,或者kill -KILL 1314。
    执行kill -l可以列出所有信号。
    4 crontab:定期执行任务进程
    进程安全
    1 程序中的多个进程同时对共享资源进行访问时,通过进程间的同步机制,能保证对资源进行安全的访问,
    不会出现数据不一致的情况,这就是所谓的进程安全。
    为什么需要引入线程
    更加轻量、需要的系统资源更少。
    1 进程是资源分配的基本单位,每创建一个进程,系统都需要分配CPU、内存、磁盘等资源。
    2 系统中不止存在一个进程,从当前进程切换到其他进程时,系统需要将当前进程的上下文信息保存下来,
    以便下一次继续执行。
    3 进程上下文信息是指进程的所有执行状态信息,保存后,切换回来时能够从切换时的状态执行下去。
    4 进程在销毁时,系统需要回收进程占用的所有资源。但由于进程的创建、切换、销毁存在较大的开销,
    因此,在80年代引入了一种能独立运行的基本单位:线程。
    5 线程成为系统进行调度和执行的最小单位。
    进程是线程的容器
    1 操作系统是进程的容器,进程是线程的容器。线程运行在进程里面,共享进程内部资源。
    2 在支持多线程的操作系统中,一个进程内部可以并发执行多个线程。
    3 线程的的执行也是有操作系统进行调度,系统会根据实际情况,将线程指定给特定的CPU核心,以进行并发计算。
    线程的通信
    1 文件方式通信
    2 所有线程共享进程的地址空间,线程间可以通过全局变量来进行通信。
    线程的主要通信是全局变量,但全局变量是来自文件流的(文件加载到内存中)
    线程的同步
    1 进程内多个线程对共享资源进行并发读写时,必须使用同步机制对线程进行协调和制约,
    以保证数据的一致性。
    2 也可以通过互斥锁,信号量来进行同步,此外还可以通过条件变量来进行同步。
    线程安全
    1 多个线程同时执行读写操作时,写操作可能造成数据的不一致,影响线程的安全,
    此时需要通过线程的同步机制来保证线程的安全。
    什么是协程
    线程是协程的容器,协程是单线程的,主要是由生成器来实现的。
    1 协程是指协同运行的、且切换和调度是由程序编写者进行设计的程序。
    2 进程和线程也是协同运行的,但他们是由操作系统进行调度的,所以不叫协程。
    3 一个协程对应一个特定的处理任务,在协程的运行过程中,程序员可以根据情况来对协程进行切换和调度
    比如当前协程处于等待状态,那就切换到其他协程,继续处理其他的任务,提高资源利用率和程序的性能
    用yied挂起,用send切换(激活)其他协程。
    例如某个协程在进行IO操作时,不会使用CPU,此时可以切换到其他协程,提高CUP的利用率。
    4 协程于进程、线程的区别还有:占用的资源极少、调度的开销也非常少,利用协程可以轻松地编写高并发
    程序。在python中,利用生成器来编写协程。
    5 IO多路复用,监控协程的状态,当协程出现阻塞,就会切换。
    multiprocessing包
    本质是一个目录
    1 python中的一个包,可以理解为模块的集合。
    2 包里有一个Process的模块,可以用来创建和管理进程。
    3 导入语法:from multiprocess import Process
    Process类的构造函数
    1 语法:Process(group=None,target=None,name=None,args=(),kwargs={},daemon=None)
    2 group:参数未使用,值始终为None
    3 target:参数未使用,值始终为None,用来传递一个可调用对象(任务对象函数)
    4 name:传递的是子进程的名称
    5 args:元组类型,传递的是target中的函数名所对应的位置参数
    6 kwargs:字典类型,传递的是target中的函数所对应的关键字函数
    7 daemon:默认值为None,设置为Ture时表示以守护进程的方式运行,子进程以守护进程运行时,
    不再受父进程的控制,必须在Process对象的start方法之前调用。
    Process对象的常用属性
    1 name:存储了进程的名称
    2 pid:存储了进程的ID号,这个ID号是系统分配的一个唯一的数字编号
    3 daemon:布尔类型,Ture表示当前进程是以守护进程的方式运行
    Process对象的常用方法
    1 Process.start():启动一个子进程,并调用该子进程的run方法,每个Process对象最多只调用一次。
    2 Process.run():启动一个子进程,会执行在构建函数中传递地方法。是start方法的一个回调函数
    与start的区别,run是在start内部调用的。
    3 Process.terminate():强制终止子进程,不会进行资源清理。(为什么不清理?意义所在?)
    4 Process.join(timeout=None):父进程等待子进程结束,子进程结束以后,父进程会回收子进程的系统资源。
    timeout表示超时时间,单位为秒。timeout默认值为None,表示该方法会一直阻塞,直到调用join()方法地进程终止。
    timeout如果传递的是一个正数,表示最多阻塞timeout秒。
    5 Process.is_alive():返回Process对象是否处于存活状态,返回值为布尔类型。实际上,Process对象从
    start()方法返回到子进程终止之前,该进程对象都处于存活状态。
    多进程通信:Pipe模块
    本质是数据交换
    1 Pipe模块是对进程管道通信机制的封装,在这种通信机制中,数据只能向一个方向流动(部分系统支持双向管道)
    单向管道又称为单工,要实现双方通信需要两个管道
    双向管道又称为双工,一个
    问题:管道是否支持双向是由系统决定的?不是模块自身的功能?
    2 管道是一种特殊的文件,数据只能向一个方向流动。
    Pipe模块的用法
    快速获取元组的元素可以使用元组解包
    1 语法:multiprocessing.Pipe([duplex])
    2 duplex的值默认为True
    多进程通信:Queue模块
    1 Queue模块是multiprocessing包下面的一个方法,返回的是一个queue对象
    2 队列本质上是通过管道来实现的。queue对象是基于FIFO(先进先出)的数据结构。
    3 队列的进程是安全的,因为使用了同步机制。(互斥锁、信号量)
    4 queue对象为进程共享,进程往队列中写入数据时,queue对象会启动一个feeder线程,
    feeder线程将缓存中的数据再写入到管道中。
    Queue对象的操作用法
    clsoe方法是减少引用的意思,子进程的关闭、文件流的关闭
    1 queue.qsize():返回队列的长度
    2 queue.empty():返回值为布尔类型,True表示队列为空,否则非空
    3 queue.full():返回值为布尔类型,True表示队列已满,否则不满
    4 queue.put(obj,[bolck[timeout]])
    obj表示要写入到队列中的数据,block的默认值为True,表示会进行阻塞,timeout用来定义阻塞的超时时间
    5 queue.put_nowait(obj):相当于queue.put(obj,False)
    6 queue.get([block,[timeout]]):从队列中读数据,block与timeout的意义同put方法中的block与timeout
    7 queue.get_nowait():相当于queue.get(False)
    8 queue.close():关闭queue对象,当前进程将不会再往队列中写入数据
    同步的优缺点:
    优点
    缺点:
    非阻塞的优缺点:
    优点:
    缺点:
    多进程通信的数据不一致问题
    1
    互斥锁与信号量
    1
    互斥锁:Lock模块
    1
    递归互斥锁:RLock模块
    1
    信号量:Semaphore模块
    1
    信号量常用操作方法
    1
    进程池
    1
    Pool类的构造函数
    1
    Pool对象常用操作方法
    1
    多线程编程
    threading模块
    1
    Thread对象常用属性和方法
    1
    线程通信
    1
    Condition对象的常用操作方法
    1 释放互斥锁(别的线程也获取不到锁,因为这是属于原子操作),是为了检查条件变量是否满足。

    IO多路复用函数:
    select.epoll