Java编程基础知识之线程篇(其一)

18 篇文章 0 订阅
11 篇文章 0 订阅

前言:

本文将对进程与线程之间的关系、各自运作做简单介绍,介绍背景基于Linux系统,因为Windows、mac不开源,无法得知内部运作

一、进程

1.什么是进程(Process)/任务(Tast)

        进程是操作系统对一个正在运行的程序的一种抽象,换言之,可以把进程看做程序的一次运行过程; 同时,在操作系统内部,进程又是操作系统进行资源分配的基本单位

2.进程控制块抽象(PCB Process Control Block) 

1)PCB基本介绍

        计算机内部要管理任何现实事物,都需要将其抽象成一组有关联的、互为一体的数据。在 Java 语言中,我们可以通过类/对象来描述这一特征。C语言使用结构体

// 以下代码是 Java 代码的伪码形式,重在说明,无法直接运行
class PCB {
    // 进程的唯一标识 —— pid;
    // 进程关联的程序信息,例如哪个程序,加载到内存中的区域等
    // 分配给该资源使用的各个资源
    // 进度调度信息
}
        这样,每一个 PCB 对象,就代表着一个实实在在运行着的程序,也就是进程。操作系统再通过这种数据结构,例如线性表、搜索树等将 PCB 对象组织起来,方便管理时进行增删查改的操作。在Linux系统下,使用的数据结构是双链表。
        

        所以基于以上:(Linux系统下)

所谓“创建线程”,就是先创建出PCB ,然后把PCB加到双向链表 

所谓“销毁线程”,就是找出链表上的PCB,并且从链表上删除

所谓“查看任务管理器”就是遍历链表

 2)PCB属性

  • pid(进程Id) :作为进程的身份标识
  • 内存指针:指明这个进程要执行的代码/指令的内存在哪里,以及这个进程执行中依赖的数据都在哪里
  • 文件描述符表
    • 程序运行过程中,经常要和文件打交道(文件是在硬盘上面的)
    • 进程每次打开一个文件,就会在文件描述符多增加一项(这个文件描述符就可以视为一个数组,里面的每一个元素又是一个结构体,对应一个文件的相关信息)
    • 一个进程只要一启动,不管代码中是否带有打开/操作文件的代码,都会默认的打开三个文件(系统默认打开),分别是标准输入(System.in)、标准输出(System.out)、标准错误(System.err)

3.CPU 分配 —— 进程调度(Process Scheduling

        操作系统对CPU资源的分配,采用的是时间模式 —— 不同的进程在不同的时间段去使用 CPU 资源。

        对于多个进程同时运行,操作系统使用的是“并发编程”,这个“并发编程”是宏观上的,微观上是两个不一样的东西,分别是【并发】与【并行】

【并行】微观上,两个CPU核心,同时执行两个任务

【并发】微观上,一个CPU核心轮流执行多个任务

并行与并发都是微观上,宏观上,人类感知不到微妙的时间差,所以宏观上我们都叫做“并发”

        为了让每个进程都调度的正确且公平,进程都有各自的状态、优先级、记账信息、上下文,被操作系统记录着
 
  • 状态:可运行状态:可运行状态表示的进程,可能没有运行,也可能已经在运行
              阻塞状态/睡眠状态:暂时不用上CPU运行
  • 优先级:优先给谁分配运行时间,其次再给谁分配时间,分配多少
  • 记账信息:统计了每个进程,都分别执行了多久,都执行了哪些命令,分别排队多少,是用来给进程调度提供指导依据 
  • 上下文:简单解释就是【存档+读档】,进程在调度的时候也是一样,进程很可能执行了某个操作,执行一半,就被调度走了,过一段时间,进程还要回来从上次执行到的位置继续往下执行!对于进程来说,上下文,具体指的就是 CPU 里的一堆寄存器里面的值。上下文就会在进程被切出 CPU 的时候,把寄存器的状态保存到 PCB 里(内存)。下次进程回到 CPU 上就把 PCB 里的上下文读取出来,恢复到 CPU 寄存器中。

4.内存分配 —— 内存管理(Memory Manage       

        进程的正常运作需要操作系统给它分配内存资源。
 
        但是如果直接分配物理地址是会出现进程A能访问到进程B的地址的错误(内存指针出现错错误),这不符合进程对隔离性的需求,所以现在的操作系统使用的是 虚拟内存地址的这一套方法,既保证了隔离性,又保证了内存资源分配

         相比于直接分配内存地址给进程,虚拟地址并不存在于实际内存中,而是假象于进程本身中,然后通过MMU做映射到实际物理内存的工作。

        虚拟内存地址给进程造成一种独享内存的错觉,内容访问也在仅在自己的虚拟内存范围内,即使内容指针出错也不会指到隔壁进程去,也就是将问题限制于自身内部。假如内容指针出错成了野指针跑到MMU中进行映射工作,也会被MMU发现,并告知指针出错

         【虚拟内存过大问题】

  1. 虚拟内存虽然很大,但是实际上使用到的物理内存很小
  2. 极端情况下,内存被吃满了,这种情况要么是bug,要么是确实有进程要使用这么多的内存。对于这种情况,要么检测bug要么增加内存。

5.进程间通信(Inter Process Communication)

        由于在资源分配的时候,就注定了两个进程之间具有隔离性,但是不同进程之间也需要进行互动交换信息。所以进程间的通信就此而生

目前主流的操作系统下的通信机制:

  1. 管道
  2. 共享内存
  3. 文件
  4. 网络
  5. 信号量
  6. 信号
        其中,网络是一种相对特殊的 IPC 机制,它除了支持同主机两个进程间通信,还支持同一网络内部非同一主机上的进程间进行通信。

二、线程     

1.线程是什么

        一个线程就是一个 " 执行流 ". 每个线程之间都可以按照顺讯执行自己的代码 . 多个线程之间 " 同时 " 执行着多份代码.
        举个例子:银行的每个服务窗口就是一个线程(银行本身就是进程)

2.为什么要有线程

  • 首先, "并发编程" 成为 "刚需".
    • 单核 CPU 的发展遇到了瓶颈. 要想提高算力, 就需要多核 CPU. 而并发编程能更充分利用多核 CPU资源.
    • 有些任务场景需要 "等待 IO", 为了让等待 IO 的时间能够去做一些其他的工作, 也需要用到并发编程.
  • 其次, 虽然多进程也能实现并发编程,但线程比进程更轻量.
    • 创建线程比创建进程更快.
    • 销毁线程比销毁进程更快.
    • 调度线程比调度进程更快.
  • 最后, 线程虽然比进程轻量, 但是人们还不满足, 于是又有了 "线程池"(ThreadPool) "协程"(Coroutine)

 补充说明:

  • 进程的资源申请和释放是比较低效的,线程之所以轻,在于资源用完不用释放,需要也就直接用,就相当于,进程一次的部署,全家终身收益。
  • 对于进程资源的申请和释放问题,虽然可以使用进程池预先准备好,但是在闲置的时候,依旧会占用大量资源

3.进程和线程的区别

  1. 进程是包含线程的. 每个进程至少有一个线程存在,即主线程。
  2. 进程和进程之间不共享内存空间. 同一个进程的线程之间共享同一个内存空间。
  3. 进程是系统分配资源的最小单位,线程是系统调度的最小单位。

         实际例子就是一个工厂内有多个流水线,多个流水线能更好的完成任务,但也不能过多,造成拥挤抢占资源变得低效,所谓物极必反。

4.Java 的线程 和 操作系统线程 的关系

        线程是操作系统中的概念. 操作系统内核实现了线程这样的机制 , 并且对用户层提供了一些 API 供用户使用( 例如 Linux pthread ).Java 标准库中 Thread 类可以视为是对操作系统提供的 API 进行了进一步的抽象和封装 .

三、线程与进程面试问题

谈谈进程与线程的区别与联系

  1. 进程包含线程,一个进程里可以有一个线程,也可以有多个线程
  2. 进程和线程都是为了处理并发编程这样的场景,但是进程在频繁的创建和释放的时候比较低效率。相比之下,线程更轻量,少了申请和释放这个过程,是直接使用进程内部已有的资源,一个进程内部的多个线程共享一个内存、文件等资源
  3. 操作系统创建进程,要给进程分配资源,进程是操作系统分配资源的最小单位。操作系统创建线程,在CPU上调度,线程是操作系统调度执行的基本单位。
  4. 进程具有独立性,每个进程有各自的虚拟地址空间,一个进程挂了,不会影响其他进程,同一个进程中有一个或者多个线程,它们共用一个内存空间,一个线程挂掉,可能影响到其他线程,甚至整个进程崩溃
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摸鱼儿hzj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值