多线程——线程与进程

发布时间:2024-08-27 15:01

多线程——线程与进程

文章目录

  • 多线程——线程与进程
    • 一、操作系统
    • 二、进程
      • 2.1 管理进程
      • 2.2 进程的调度(并发&并行)
      • 2.3 PCB 进程控制块
      • 2.4 进程的独立性
    • 三、多线程
    • 四、面试题

前言:

全是概念,概念篇,多多理解,知道整个流程是什么样子的。

一、操作系统

操作系统是计算机里面最重要的一个 软件

操作系统这个软件主要完成两个工作:

1、管理计算机的各种硬件设备

2、给计算机上各种软件资源提供稳定的运行环境;

先来看一张图,了解下操作系统在计算机里面的那个位置;

\"多线程——线程与进程_第1张图片\"

由图可知,操作系统在整个计算机的中间的位置,因为操作系统两边都要管,软硬件通吃。

操作系统如何管理硬件:

可以以生活中来举列子,操作系统相当于是一个管理者,学校的校长,校长是不会把具体的通知单独传给具体学生的,而是通过辅导员来 deliver 信息。那么操作系统也是不会直接操作硬件,而是给 驱动 发动施令,再由 驱动 来对硬件具体操作。

因为硬件是有不同的厂家生产的,操作系统不可能理解每个厂家硬件的细节,然后我们 就用 操作系统统一定义的一套接口,然后由各个硬件厂商来实现对应的驱动程序,做到和操作系统对接的效果。

  • 更形象的例子
System.out.println(\"hell world\");
在这个代码中看似简单,但是内部的过程是繁琐的;
  >	首先会在 println方法的内部,调用操作系统提供的API(C提供的,是一个交write的函数),通过系统调用 write ,就会进入到操作系统的内核,在内核中执行;
  >	然后操作系统内核就会找到显示器的驱动,然后把要 deliver 的信息给驱动;
  >	最后再由显卡驱动来操作显示器硬件,然后但因在屏幕上。

二、进程

这里我们主要还是来深究 操作系统管理 非常重要的软件资源,叫做“进程“(process/task)。

双击运行一个 .exe 文件,操作系统里面就会运行一个对应的\"进程\",这个时候CPU就会一条一条的来执行这个程序里面的指令。也可以打开电脑上的任务管理器,那里面的东西就是进程。

2.1 管理进程

​ 计算机里面的程序有多个,操作系统又是怎么管理“进程”的尼??

操作系统要能够保证多个进程,每个都能正常工作,并且互不干扰

管理分为:描述 + 组织 (这里是Linux做法,Windows and Mac 都不开源)

描述:操作系统内部使用的是一个结构体,一个进程需要那些信息都会在结构体里面有所体现。操作系统描述进程的结构体称之为 PCB(process control block)进程控制块。

组织:这里的底层是一个双链表,任何一种组织,管理的底层都是数据结构,通过双链表把所有的PCB给连在一起。

执行过程:运行一个 .exe 程序,进入了进程,操作系统内核自动创建 PCB,然后把PCB 加到双向链表中,关掉一个程序,操作系统就会找到对应的 PCB ,并且从双向链表中删除;当我们在 Windows里面打开任务管理,那么里面显示的进程信息,就是双向链表在遍历。

\"多线程——线程与进程_第2张图片\"

2.2 进程的调度(并发&并行)

上面也说了操作系统要能够保证多个进程,每个都能正常工作,并且互不干扰,从而就引出了 “调度“这个概念。

现实生活中也有 调度 这个岗位,比如说火车调度员,主要的工作职责是 负责该管辖列车及机车的调动与走行,尤其是当某一区段的线路被迫中断或出现紧急情况的时候影响安全运行,就需要列车调度员向出现危急情况的路段周围车站及机车驾驶员发布调度命令,要求后面列车采取慢行,紧急制动或救援的命令。

这里的调度员就是让火车行驶之间互不干扰,不扰乱秩序减少交通事故,那么在进程里面的情况也是这个样子,让进程和进程之间互不干扰,正常工作。


操作系统为了能够 调度,所以就给 PCB 增加了几个属性:

  • 并行:2个核心,同时在执行两个进程的指令;
  • 并发:1个核心,“同时”在执行多个进程指令,这里的同时指的是 快速的切换。
    • such as:1.9GHz ==> 每秒执行 19亿条指令

现在的操作系统,都是支持多任务的操作系统,这个多任务之间就是通过 并发+并行 的方式来调试执行的,通常情况下往往使用并发来代替指 并行+并发

2.3 PCB 进程控制块

尽然 PCB 是一个结构体,那么它里面就会有很多的属性 和字段 ,这里介绍重点的字段:

1、pid : 进程的身份标识 id;

2、内存指针:描述进程使用的内存是那些范围;

a、可执行文件是在硬盘上的,双击运行就会启动进程,会把硬盘上面的数据加载到内存中,然后内存包含了程序所对应的 指令 是什么(代码段),依赖的数据是什么 (数据段);内存指针就是描述了哪里是代码段,那里是数据段。

3、文件描述符表:描述了进程都打开了那些文件。

a、文件描述符表视为一个数组,数组中的每一个元素是一个结构体,描述的是文件的信息,这个数组的下标成为“文件描述符”;
b、每个文件一启动,默认会打开三个文件(在文件描述符表中创建三个项),分别是 标准输入(System.in),标准输出(System.out),标准错误(System.err),如果通过代码打开其他文件,同样也会在文件描述符表中创建出对应的项。

从前面三条也可已看出 PCB 描述了给进程都分配了那些硬件资源,可以认为进程就是操作系统进行资源分配的基本单位; 只要运行一个进程,那就会给这个进程分配一些内存空间。

4、进程的状态

描述了当前进程,是否能够去 CPU 上执行。

主要分为两大状态:

1、就绪状态:已经在CPU上了,随叫随到

2、阻塞状态/ 睡眠状态:不在线上,不能随叫随到。

5、优先级

这个是在进程“调度” 的时候,给每个进程安排的时间和先后都可以存在差别。

6、上下文

这个概念有点难理解,操作系统执行到某个进程的时候,如果要把进程从CPU上调走,就需先保存CPU的运行场景(寄存器里面的数值),保存到内存中,等到下次在调度到这个进程的时候,就可以继续从上次的位置往后执行。也可以理解成游戏里的 存档和读档操作 。

7、记账信息

统计的是每个进程执行的时间和指令的数目,依据这个来平衡调度的效果。

2.4 进程的独立性

进程的“独立性”是一个非常重要的特性,操作系统会给每个进程都分配一个独立的 “虚拟地址空间”,这样就能够保证进程互相之间无法产生影响。

1,独立性,独立是为了确保操作系统要个软件提供一个 ”稳定的运行环境“
a、“稳定的运行环境” 是指让系统能够保证,一个进程出问题,不会涉及影响其他的进程,也不会波及整个系统。

2、”虚拟地址空间“,保证当前的进程和进程之间,访问的内存,没有“公共的空间区域” (各自访问各自的,互不干扰)来形成“稳定的运行环境”。如果A进程把内存破坏了,此时不会对B,C进程有任何的影响,也不会对整个系统直接产生关联,因为他们没有 “公共的空间区域”,就互相不影响,此时 B,C 根本就不使用A的内存。


虽然,进程之间存在“独立性”,但是多数的时候,他们还是避免不了进程互相配合来完成一些特定的工作!!!

❓那么要这么样才能让进程在有“独立性”的这个性质外,又让进程之间有 contact 尼??

  • 这里操作系统就提供了一些==“进程间通信”== 的机制,可以让进程在有限的情况下进行一些 contact 操作

\"多线程——线程与进程_第3张图片\"

通过这样的方式,就保证了大家都互不干扰,但是也可有微许联系,这样子做可能显得不方便,但是确保了整体系统的稳定性

这样也解释了 ”进程键通信机制“就是在进程独立性这个要求之上,开一个口子,提供专门的一些区域,可以让多个进程之间能够同时访问,共享。

操作系统提供的进程间通信的机制,有多种,这里比较重要的就有两种:

1、操作文件;

2、操作网络;(Mysql客户端访问 mysql 服务器,同一个机器上的两个进程通过网络来交互数据)。

三、多线程

❓ 有了多进程,为啥还有 多线程 这个东西???

一、搞清楚进程是干什么的;

  • 进程主要是为了解决 “并发编程“ 的问题,如果没有 ”多任务操作系统“ 的时候,那么也不会有 ”进程“了,但是现在的电脑和手机基本上都是 ”多任务操作“。

多进程确实可以解决 并发编程 的问题,但是他也带来了其他的问题!!!

如果当并发执行的任务比较多的时候,任务之间切换比较繁忙的话,这个时候成本就会比较的高,尤其,是频繁的创建和销毁任务操作的时候,是比较低效的状态。

  • 为啥说是低效,开销比较的大?
    • 主要的原因是进程持有的系统资源是比较多的,创建进程就需要分配资源,销毁进程就需要释放资源,进程调度切换,也需要让系统在这些资源之间进行切换,然而这些操作都是比较耗资源的操作。

这里也引入了两个解决的办法:

​ 1、进程池;(类似于字符串常量池)

​ 2、通过线程来解决问题;

​ (1)、线程也可以叫做 “轻量级进程” ,LWP (light weight process) [Linux]。

二、线程。

1、理解线程:

​ 假如在工厂需要生产1W个单片机,单片机生产的数量很多,又要快速的生产完,有两种解决的方式:

​ (1)、多建工厂,建立两个工厂生产单片机;

这个方案成本开销就非常的大,首先要找场地,其次每个工厂还要有工厂的设备…

​ (2)、在同一个工厂中,搞多条生产线出来;

这个方案是需要一个场地,在原来的场地下,多搞一套生产设备,两个生产线就可以同时运行。

这么一看肯定就是第二种方案好了,我的线程就可以看做 生产线 ,而进程就是 场地 ,每个线程都是单独干活(执行一组独立的代码),同一个进程里面就会有若干条线程,他们之间都是共有的场地(内存空间)。

2、现在又回到解决并发的问题,借助多线程也是可以解决“并发编程”的。

​ 但是仍需要频繁的创建销毁任务,此时只需要创建销毁线程就可以了,资源是绑定在进程身上的,创建/销毁线程,和进程上的资源关系就不大。创建线程并不需要分配新资源,资源给了进程,销毁线程也不需要释放旧的资源,CPU针对线程进行调度,开销也是小于进程的。

补充:现在的CPU工艺都是有很大的改进,传统意义上,一个CPU核心,微观上同时只能执行一个线程,但是现在,一个核心可以同时执行两个线程。

例如:Intel 12 代,大小核机制,16核 24线程(大核心,微观上同时执行两个线程,小核心,微观上同时执行一个线程)。

按照编程的角度来讲,还是认为传统意义上的观点。


总的来说,多线程比多进程更适合“并发编程”。

这里概念居多,也难以理解,所以就形成了面试的“必考题”。

四、面试题

谈谈进程和线程之间的关系和区别。

1、线程是包含在进程里面的。(最重要的观点)

2、每个线程都是独立的执行流。(各自执行一段自己的代码)

3、同一个进程中的线程之间,共用同一份资源(虚拟地址空间+文件描述表)

​ 线程A的变量,线程B也可以用到;线程A打开的文件,线程B也是可以用到。

4、从操作系统的角度看,可以认为 进程是资源分配的基本单位 ,线程是CPU调度执行的而基本单位。

学了多线程之后,前面的”进程调度“更准确来说是“线程调度”。叫 “进程调度” 也可以,毕竟线程可以叫做是“轻量级进程”。


这篇的帖子纯属概念,但是你又不能不理解,因为进程和线程是面试中的必考题,这里的概念只有多多理解,然后,问到进程和线程之间的关系和区别就背这个八股文给面试官听

铁汁们,觉得笔者写的不错的可以点个赞哟❤,收藏关注呗,你们支持就是我写博客最大的动力!!!!

\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号