zoukankan      html  css  js  c++  java
  • 进程和线程

    内容来自GreenPills的github笔记,补充记录

    1.并发和并行

    • 并发指的是宏观上在一段时间内可以同时运行多个程序,但是微观上俩个程序的命令是交织进行的,不能提高计算机性能,只能提高效率
    • 并行则是指同一时刻运行多个指令,比如借助多核CPU。

    2.死锁的条件和解决办法

    死锁发生要满足四个条件:

    · 互斥条件 某个资源在一段时间内只能由一个进程占有。只有在该进程主动释放它后,其它进程才能主动释放它。比如打印机。

    • 不可抢占条件 **进程所获得的资源在未使用完毕之前,资源申请者不可以强行从资源占有者手中夺取资源,只能由资源占有者进程自行释放。
    • 占有且申请条件 进程至少已经占有一个资源,但又申请新的资源 由于该资源已被其他进程占有,此时进程阻塞,但是仍然占用资源。(不是一次全申请完,申请了会占用)
    • 循环等待条件 **存在一个进程等待的序列,{P1,P2...Pn},其中P1等待P2所占用的某个资源,然后P2等待P3占用的某个资源,最后Pn等待P1占用的某个资源,形成一个进程循环等待的环。

    预防:预防是保证系统不进入死锁状态的策略。

    对四个条件的破坏,互斥条件不能破坏(没用)

    • 破坏不可抢占条件,即可抢占式,要求申请失败的进程释放自己占有的资源给别人用。
    • 破坏占有且申请条件。 直接申请自己所需要的所有资源。问题是(1.不可预知自己需要什么资源,2、资源利用率很低,长期占有自己可能不用的资源)
    • 破坏循环等待条件。

    避免 死锁的避免是指不限制进程有关申请资源的命令,对进程所发出的每一个申请资源命令加以动态地检查,并根据检查结果决定是否进行资源分配。(不破坏条件,对申请情况进行检查,可以就分配)比如说银行家算法。进程申请资源时候,先试探分配给该进程,然后根据安全性算法判断分配后地系统是不是处于安全状态,不安全就继续等待。

    判定安全状态:已分配资源、还需要的资源、可用的资源、finish判定符。

    3.进程

    程序运行的实例,是程序向操作系统申请资源(比如内存空间)的基本单位。是该程序的可执行机器码在内存的拷贝。

    • 进程可能的状态有:新生(进程产生),运行态(正在运行),等待态(也叫阻塞,等待某个事情发生,比如等待用户输入),就绪态(排版中,等待CPU),结束(完成运行)。
    • 私有和共享的资源:私有(地址空间、堆、全局变量、栈、及寄存器),共享(代码段、公共数据、进程目录,进程ID)

    进程间通信

    【1】管道(pipe):管道有俩种,它是标准的输入输出链接起来的一系列过程,一个进程的输出作为下一个进程的输入。

    • 无名管道:构建一个匿名管道,在进程中打开俩个打开的新的文件描述符:一个只读端和一个只写端。它是一种半双工的同学方式,只可以在具有亲缘关系的进程中去使用(比如说父子进程,兄弟进程) 调用的int pipe(int fd[2]),fd[0]为了读打开,fd[1]为了写打开,关闭只需要把这俩个文件描述符关掉。
    • 有名管道。调用时表现为输入或输出文件。命名管道时一个设备文件,存在在文件系统中,类似io进程利用文件传输数据,所以即使不存在亲缘关系,只要能访问路径,就可以通过有名管道相互同学,也是半双工的,但是运行没有亲缘关系进程的通信。
      优缺点:无名管道(优点:简单方便,缺点:单向通信,需要亲缘关系,缓冲区有限),有名管道(有点:实现任意关系的进程间通信,缺点:长期存在于系统中,使用不当容易出错)

    【2】信号量(也叫信号标),可以看作一种具有原子操作(不可以中断的操作,要么做了要么没做)的计数器,用于保持在0到指定最大值之间的一个计数值。用来控制多个进程对共享资源的访问,通常来描述临界资源(公用的设备,或者是存储器)的数目, 当作锁(lock)来使用,防止一个进程访问另一个进程正在使用的资源。实现互斥和同步的操作。提供一种机制:让一个临界区同一个时刻只能有一个进程(执行流)来访问它。

    • 临界区:一段代码 再这段代码中,进程将访问临界资源,当有进程进入临界区时,其他进程必须等待,有一些同步机制必须再临界区段进入点和离开点实现,确保这些共用资源被互斥所获得。
    • 原理: 1、测试控制该资源的信号量,2、如果是正的,则进程可以用该资源,然后进程把信号量减1,表示有一个资源被使用了。3、如果信号量为0,该进程进入休眠状态,知道信号量大于0,则进程唤醒,重新去使用进行第一步。4、当进程不在使用一个信号控制的共享资源,就把信号量增加1。如果有休眠进程,就唤醒。(信号量操作应是原子操作,所以通常再内核中实现)
      【3】信号(signal),是一种异步的通知机制,用来提醒进程一个事情已经发生。一个信号发送给进程时,所有非原子操作会被中断,如果进程定义了信号的处理函数,就会执行,否则就执行默认的处理函数。
      【4】消息队列:是一种进程间通信或者是同一个进程中,不同线程间的通信方式,提供异步的通信协议,每一个队列中包含详细说明的数据,包含发生的时间,输入设备的种类,以及特定的输入参数。
      特点:1、异步、允许接收者再消息放松很长时间后再取回消息。2、接收者必须轮询消息队列,才能收到最近的消息、3、信息复制需要消耗额外的cpu时间。
      【5】内存共享 进程间通信最快的方式,共享内存所有进程都可以访问,所以需要加锁。映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,多个进程都可以访问。(优点:无需复制、快捷,信号量大,缺点:利用内存缓存区来交换信息,不方面网络通信,只能再同一个计算机系统中的诸多进程共享)
      【6】套接字 socket,以ip地址和通信端口组成套接字地址。完成连线后,可以用于不同主机之间的进程通信。

    4.线程

    线程是操作系统能进行运算调度的最小单位,被包含在进程汇总,是进程的实际运作单元。一条线程指的是进程中一个单一顺序的控制六。一个进程可以并发多个线程,每条线程并发执行不同任务。是独立调度和分派的基本单位。
    同一进程的多条线程共享进程全部的系统资源(比如说虚拟地址空间,文件描述符)但同一个进程中的多个线程有各自的调用栈,自己的寄存器环境,自己的线程本地存储。

    • 状态:新建(new,创建线程但是没有开始允许线程中的代码。)、就绪状态(创建线程资源,start)、运行态(获得cpu资源,线程开始运行)、阻塞状态(线程未结束,但是出让cpu)、死亡态(线程结束,正常退出结束,或者是异常死亡)

    线程间的通信

    【1】锁。包括互斥锁(mutex,以排他的方式,防止数据结构被并发修改,当资源占用,申请者进入睡眠状态)、读写锁(允许多个线程同时读共享数据,但互斥锁)、自旋锁(类似互斥锁,为了保护共享资源,循环检测保持者是否释放锁。)、条件变量(以原子的方式阻塞进程,直到某个特定条件为真,和互斥锁一起使用,对条件的测试是在互斥锁保护下进行的)。
    【2】信号量
    【3】信号

    5、进程线程异同

    • 进程是向操作系统申请资源的最小单位,线程是cpu调度和分派的最小单位。
    • 一个进程至少有一个线程,可以有多个线程,线程依赖进程存在,一个线程只能属于一个进程。
    • 进程有自己独立的内存单元,多个线程共享进程的内存,一个进程中所有的线程都共享该进程的全部系统资源(全局变量,静态变量,对存储,代码和常量)、每个线程有自己的栈段,存放局部面两和临时变量。
    • 系统开销上,创建和撤销进程都需要去分配回收资源(启动一个进程,系统需要给他分配地址空间,建立数据表维护代码段、堆栈段、数据段。)开销比线程大,进程切换时,还要保存当前进程的cpu环境,设置新调度的进程cpu环境。而线程只需要保存和设置一些寄存器的内同,所以切换上进程的开销也比线程大。
    • 线程间通信比较容易(有相同地址空间,共享全局变量,静态变量等数据),进程间通信比较难。多线程程序考虑如何处理好同步和互斥。
    • 多进程程序更加健壮,因为多线程程序一个进程挂掉,整个进程就挂掉了,但进程挂掉不会对另一个进程有影响(不同地址空间)
  • 相关阅读:
    edgecore
    十问 Linux 虚拟内存管理 (glibc)
    Covered Path
    Journey Planning
    K for the Price of One
    Candies!
    2种方式解决nginx负载下的Web API站点里swagger无法使用
    分布式环境下的数据一致性问题的方案讨论
    static,你还敢用吗?
    分离EF connectionString里的db连接串
  • 原文地址:https://www.cnblogs.com/EvansPudding/p/12698707.html
Copyright © 2011-2022 走看看