进程

进程的组成

进程是操作系统中分配资源的最小单位。进程由 3 个部分组成,分别是程序代码数据集、栈进程控制块(PCB)

各自的作用如下:

  1. 程序代码:描述了进程需要完成的功能。

  2. 数据集、栈:程序在执行时所需要的数据和工作区。

  3. 进程控制块:包含进程的描述信息和控制信息,它是进程存在的唯一标识。

  4. PCB:用来描述和控制进程运行的通用数据结构,是进程能够独立运行的基本单位。(常驻内存,存在系统专门开放的PCB块)

进程的状态

  1. 创建态,分配PCB块,插入就绪队列,还未申请其他资源
  2. 就绪态,拥有除了CPU以外的资源
  3. 运行态,进程获得CPU执行权,正在执行
  4. 阻塞态,由于某种原因,位于阻塞状态,放弃CPU
  5. 终止态,进程结束后由系统清理并归还PCB块

进程通信

信号signal:通过向一个或多个进程发送异步事件信号来实现,如:SIGSTOP、SIGKILL等信号。

管道pipe:在两个进程之间,可以建立一个通道,一个进程向通道写入字节流,另一个进程从管道读取字节流。管道是同步的,当进程尝试从空管道读取数据时,该进程会被阻塞,直到有可用数据为止。如linux的 | 管线

共享内存:通过共享内存进行进程间通信,一个进程所作的修改对另一个进程可见。

先入先出队列FIFO:也称命名管道,具有支持文件和独特 API ,命名管道在文件系统中作为设备的专用文件存在。而非命名管道在结束后缓冲区会被系统回收。

消息队列:描述内核寻址空间内的内部链接列表。可以按几种不同的方式将消息按顺序发送到队列并从队列中检索消息。每个消息队列由 IPC 标识符唯一标识。

套接字Socket:提供端到端的双向通信,可有TCP、UDP的支持。

进程同步

临界资源:指的是一些虽作为共享资源却又无法同时被多个进程或线程共同访问的共享资源。为了对临界资源进行有效的约束,就提出了进程间同步的四个原则

  • 空闲让进:资源无占用,允许使用

  • 忙则等待:资源被占用,请求进程等待

  • 有限等待:保证有限等待时间能够使用资源,避免其它等待的进程僵死

  • 让权等待:等待时,进程需让出CPU,也就是进程由执行状态变为阻塞状态,这也是保证CPU可以高效使用的前提

死锁

死锁定义:如果一组进程中的每个进程都在等待一个事件,而这个事件只能由该组中的另一个进程触发,这种情况会导致死锁

死锁的条件

  1. 互斥条件:资源是排他性使用的
  2. 保持和等待条件:已拥有资源的进程不释放自己的资源,去申请新的资源
  3. 不可抢占条件:进程未使用完的资源不能被其他进程剥夺
  4. 循环等待:死锁发生时,必存在资源环形链路

处理死锁策略

  1. 鸵鸟算法(忽略死锁带来的影响)
  2. 检测死锁并恢复死锁,死锁发生时对其进行检测,一旦发生死锁后,采取行动解决问题(分配时监测是否会发生死锁,可以通过回滚、抢占、杀死进程恢复死锁)
  3. 通过合理分配资源来避免死锁(银行家算法,根据空闲资源表和资源需求表合理分配资源)
  4. 通过破坏死锁产生的四个条件之一来避免死锁
    • 破坏互斥条件
    • 破坏保持等待条件
    • 破坏不可抢占条件
    • 破坏循环等待条件

两阶段加锁

一种解决方式是使用 两阶段提交(two-phase locking)。顾名思义分为两个阶段,一阶段是进程尝试一次锁定它需要的所有记录。如果成功后,才会开始第二阶段,第二阶段是执行更新并释放锁。第一阶段并不做真正有意义的工作。

如果在第一阶段某个进程所需要的记录已经被加锁,那么该进程会释放所有锁定的记录并重新开始第一阶段。从某种意义上来说,这种方法类似于预先请求所有必需的资源或者是在进行一些不可逆的操作之前请求所有的资源。

通信死锁

进程 A 给进程 B 发了一条消息,然后进程 A 阻塞直到进程 B 返回响应。假设请求消息丢失了,那么进程 A 在一直等着回复,进程 B 也会阻塞等待请求消息到来,这时候就产生死锁

解决方法:超时重传

**进程间同步的方法:**消息队列、共享存储、信号量。会在后边的文章中详细介绍这些进程间同步的方法

fork进程

  • fork系统调用是用于创建进程

  • 对于虚拟空间地址来说,子进程会拷贝父进程的虚拟地址空间。所以,fork后子进程的用户区与父进程的用户区相同,也会拷贝内核区内容,仅仅是进程的 pid不同。

  • 在父进程中返回子进程的ID,在子进程中返回0。所以可以通过fork 的返回值来区分父进程与子进程

  • fork系统调用无参数

运用了读时共享、写时拷贝的原则,fork后,父子进程共享父进程的地址空间(只读),在父进程或者子进程进行写指令时,子进程才会复制一份地址空间,从而使得虚拟地址空间独立,在自己的地址空间进行写操作。也就是说,资源的复制是在需要写入时才会进行,在此之前,只会以只读方式进行共享

进程类型

前台进程:具有终端,可以和用户进行交互的进程

后台进程:不与用户进行交互,优先级比前台进程低

守护进程:特殊的后台进程

孤儿进程:父进程退出后,子进程即成为孤儿进程,将由**init进程(pid为1)**收养

僵尸进程:子进程的进程描述符在子进程退出后不会释放,只有当父进程调用**wait()、waitpid()**获取子进程信息才释放

线程

线程是操作系统进行运行调度的最小单位,线程除了拥有自己的栈、程序计数器等资源外,共享进程的资源。

通信,对于进程来说是进程间的通信(IPC),而对于线程,它是通过读写同一个进程的数据进行通信。

线程同步

互斥量

  • 本质上是资源排他性使用,效果相当于原子性。拥有两种状态:加锁和解锁。(会带来相关损耗,阻塞锁

    • 自旋锁:等待获取资源的时候CPU不会释放,优点:如果线程占用锁时间不长,就能避免上下文切换代价;缺点:耗费CPU时间
    • 读写锁:读不进行加锁,写的时候进行加锁,对于多读少写的情况,性能能有很好的提升

信号量:表示同时允许访问资源的最大线程数量,它是一个全局变量。(Java的semaphore)

条件变量:利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待某个条件为真,而将自己挂起;另一个线程设置条件为真,并通知等待的线程继续。条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定的条件发生。

  • 基本动作:wait、signal、notify

调度算法

  • 调度算法的目标:

  • 先来先服务:按照FIFO的原则,将作业加入到就绪队列中,按照顺序调度作业。

  • 最短作业优先:按照线程作业的CPU时间片,优先调度所需最短CPU时间片的作业。

  • 最短剩余时间:最短作业优先的抢占式版本,总是调度剩余运行时间最短的作业。

  • 轮询调度:每个作业都会被分配一个CPU时间片,在这个时间片内允许进程运行。如果时间片结束时进程还在运行的话,则抢占一个 CPU 并将其分配给另一个进程。

  • 优先级调度:按照作业优先级进行调度。

  • 多级反馈队列:设置多级队列,设置不同优先级,并且分配不同的时间片。

POSIX线程

即线程标准。

线程调用 描述
pthread_create 创建一个新线程
pthread_exit 结束调用的线程
pthread_join 等待一个特定的线程退出
pthread_yield 释放CPU来运行另外一个线程
pthread_attr_init 创建并初始化一个线程的属性结构
pthread_attr_destory 删除一个线程的属性结构

线程实现

在用户空间实现线程

内核并不知道线程的存在,以进程为单位分配CPU时间片,每个进程要有专用的线程表。

优点:允许每个进程有自己定制的调度算法、调度效率比内核调用高(无需陷入内核,即上下文切换,无需刷新内存高速缓存)

缺点:会因为阻塞调用/缺页中断阻塞整个进程直到完成

在内核空间实现线程

内核中会有用来记录系统中所有线程的线程表,当进行系统调度的时候,会通过对线程表的更新进行调度。线程表拥有每个线程的寄存器、状态和其他信息。

优点:不会因某个线程阻塞而导致进程阻塞

缺点:系统调用代价大,上下文切换开销大,以及需要切换系统状态

混合实现:将用户级线程与某些或者全部内核线程多路复用起来。编程人员可以自由控制用户线程和内核线程的数量,具有很大的灵活度。内核只识别内核级线程,并对其进行调度。其中一些内核级线程会被多个用户级线程多路复用。

了解更多文章,

程序员不得不学的操作系统知识(二)相关推荐

  1. 程序员不得不学的操作系统知识(三)

    存储器管理 存储器层次结构 存储层次至少具有三级:最高层为CPU寄存器,中间为主存,最底层是辅存. 程序的装入和链接 程序装入方式: 绝对装入方式:绝对装入程序按照装入模块的地址,将程序和数据装入内存 ...

  2. 程序员不得不学的操作系统知识(一)

    计算机硬件 计算机的重要组成部分,包含了 5 个重要的组成部分:运算器.控制器.存储器.输入设备.输出设备. 运算器:运算器最主要的功能是对数据和信息进行加工和运算.它是计算机中执行算数和各种逻辑运算 ...

  3. 软考 程序员教程-第二章 操作系统基础知识

    软考 程序员教程-第二章 操作系统基础知识 第二章 操作系统基础知识 2.1.操作系统概述(第四版教程P44) 操作系统的4个特征:并发性.共享性.虚拟性.不确定性. 操作系统的5个功能:处理机管理. ...

  4. 后端程序员必备的 Linux 基础知识

    后端程序员必备的 Linux 基础知识 原文来自github stars>63k的项目JavaGuide,欢迎小伙伴去支持原作者 一 从认识操作系统开始 1.1 操作系统简介 1.2 操作系统简 ...

  5. 程序员的灯下黑:重知识轻技术(转)

    为什么80%的码农都做不了架构师?>>>    程序员的灯下黑:重知识轻技术(转) 电视<雍正王朝>讲了这么一个故事:大将军年羹尧奉命到青海平叛,清军因路途遥远,军耗巨大 ...

  6. 一不小心就触碰红线...程序员必须知道的法律知识有哪些?

    很多程序员空有一身本领,却不注重法律意识的培养,于是造成了很多不可估量的后果. 话不多说,直接先上实例: 实例一 10 月 7 日,丰田汽车发现,296019 名客户的电子邮件地址和客户编号可能已被泄 ...

  7. Java数据结构与算法面试题,首发Java程序员人手必备的进阶知识体系,(1)

    在市场上很少能够看到一套不错的学习笔记,小编也是花了挺久的时间总结了这份**<Java程序员人手必备的进阶知识体系>**,帮助大家系统化高效的进阶学习,而不是零散低效的阅读. 2020全新 ...

  8. 程序员必知的操作系统知识点

    这是一本关于程序员必知的操作系统,可以看一下目录. 内容涉及 认识操作系统 进程和线程 内存管理 文件管理 I/O 死锁 操作系统面试题 操作系统核心概念 字是一个一个敲的,图是一笔一笔画的. 可以看 ...

  9. C程序员必须知道的内存知识【英】

    C程序员必须知道的内存知识[英] 时间 2015-03-08 14:16:11 极客头条原文  http://marek.vavrusa.com/c/memory/2015/02/20/memory/ ...

最新文章

  1. 如何做好网络推广“放大招”,教你如何更快速的给新上线网站关键词排名?...
  2. ASP.NET MVC和jQuery DataTable整合
  3. python组合数据类型有哪些_Python学习之组合数据类型
  4. python处理表格数据教程_用Python的pandas框架操作Excel文件中的数据教程
  5. 数学建模传染病模型_数学建模| 时间序列模型
  6. TwoSum,从O(n^2)到O(nlogn)再到O(n)
  7. php获取当前时间戳方法
  8. java linux at_linux下运行java程序报错,求大神解答
  9. 分布式架构之缓存系统
  10. HTML5七夕情人节表白网页制作【自定义文字-烟花告白】HTML+CSS+JavaScript浪漫烟花表白网页制作
  11. JS实现文件的上传与下载
  12. CAD学习笔记中级课【模板样式】
  13. 亚马逊卖家运营必备八大工具
  14. 闯关H5小游戏制作推荐,教你快速上手TOM闯关游戏H5
  15. 世界第 3 的滴滴裁员,求职季必知的独角兽公司排行榜
  16. 国瀚实业|打算投资理财,这些事要准备好
  17. 什么是时间复杂度与空间复杂度
  18. Mac保留文件重装系统
  19. 如何使用 Axios 中的请求拦截器 和响应拦截器
  20. 抖音跳转到微信引流的方法,私信页面如何添加微信

热门文章

  1. 重新回头学习归纳ES6的知识点-------promise(承诺)
  2. java8 .map是什么意思_JDK8 stream().map() 作用
  3. ViewPager简单介绍(一)
  4. matlab中绘制三维散点图scatter3函数的使用方法(附matlab代码)
  5. Delaunay三角剖分及matlab实例
  6. Android通过DownloadManager实现App的版本更新功能
  7. 数据结构与算法之美(二)
  8. c语言组建怎样变成编译,c语言编译【处理流程】
  9. abp生成proxy代理时的一些问题记录
  10. 多对多维度或多值维度-桥接表