线程(Thread)的基本概念

简介: 线程(Thread)的基本概念

背景

如果说,在OS中引入进程的目的是为了使多个程序能并发执行,以提高资源利用率和系统吞吐量,那么,在操作系统中再引入线程,则是为了减少程序在并发执行时所付出的时空开销,使OS具有更好的并发性。为什么?

进程的两个基本属性

首先让我们来回顾进程的两个基本属性:

① 进程是一个可拥有资源的独立单位,一个进程要能独立运行,它必须拥有一定的资源,包括用于存放程序正文、数据的磁盘和内存地址空间,以及它在运行时所需要的I/O设备、已打开的文件、信号量等;

进程同时又是一个可独立调度和分派的基本单位,一个进程要能独立运行,它还必须是一个可独立调度和分派的基本单位。每个进程在系统中有唯一的PCB,系统可根据其PCB感知进程的存在,也可以根据其PCB中的信息,对进程进行调度,还可将断点信息保存在其PCB中。反之,再利用进程PCB中的信息来恢复进程运行的现场。正是由于进程有这两个基本属性,才使进程成为一个能独立运行的基本单位,从而也就构成了进程并发执行的基础。

程序并发执行所需付出的时空开销

为使程序能并发执行,系统必须进行以下的一系列操作:

(1) 创建进程,系统在创建一个进程时,必须为它分配其所必需的、除处理机以外的所有资源,如内存空间、I/O设备,以及建立相应的PCB;

(2) 撤消进程,系统在撤消进程时,又必须先对其所占有的资源执行回收操作,然后再撤消PCB;

(3) 进程切换,对进程进行上下文切换时,需要保留当前进程的CPU环境,设置新选中进程的CPU环境,因而须花费不少的处理机时间

线程——作为调度和分派的基本单位

如何能使多个程序更好地并发执行,同时又尽量减少系统的开销,已成为近年来设计操作系统时所追求的重要目标。有不少研究操作系统的学者们想到,要设法将进程的上述两个属性分开,由OS分开处理,亦即并不把作为调度和分派的基本单位也同时作为拥有资源的单位,以做到“轻装上阵”;而对于拥有资源的基本单位,又不对之施以频繁的切换。正是在这种思想的指导下,形成了线程的概念。

线程与进程的比较

1.调度的基本单位

进程:在传统的OS中,进程作为独立调度和分配的基本单位,

线程:而在引入进程的操作系统中。线程变成了资源调度和分派的基本单位,可以把线程理解成 “轻量级进程”。

2.并发性

进程与进程:进程和进程可以实现并发。

进程内的各线程:也可以实现并发,从而进一步提升了并发性

3.拥有的资源

进程: 进程可以拥有资源,并作为系统中拥有资源的一个基本单位。

线程: 线程只拥有少量的,能保证独立运行的资源,还允许多个线程共享资源。

4.独立性

同一进程内的不同线程: 独立性低, 因为同一进程内的不同线程是为了提高并发性和相互之间的合作而创建的,他们共享进程内的地址空间和资源。

不同进程内的不同线程: 独立性高,为了防止进程之间彼此干扰和破坏,每个进程都拥有一个独立的地址空间和其他资源,除了共享全局变量以外,不允许其他进程访问。

5.系统开销

进程:开销大。在创造或撤销进程时,系统都要为之分配和回收PCB,分配或回收其他资源(如I/O设备)

线程:开销小。不需要涉及PCB的分配,系统开销明显小于进程。并且切换线程的代价也远低于进程的切换。

6.支持多处理机系统

单线程进程: 在多处理机系统中,进程只能运行在1个处理机上。

多线程进程: 在多处理机系统中,进程可以在多个处理机上并发运行,无疑加速了进程了完成。

线程的状态与线程控制块

线程运行的三个状态

与传统的进程一样,在各线程之间也存在着共享资源和相互合作的制约关系,致使线程在运行时也具有间断性。相应地,线程在运行时也具有下述三种基本状态:

(1) 执行状态,表示线程已获得处理机而正在运行;

(2) 就绪状态,指线程已具备了各种执行条件,只须再获得CPU便可立即执行;

(3) 阻塞状态,指线程在执行中因某事件受阻而处于暂停状态,例如,当一个线程执行从键盘读入数据的系统调用时,该线程就被阻塞。

线程控制块TCB

如同每个进程有一个进程控制块一样,系统也为每个线程配置了一个线程控制块TCB,将所有用于控制和管理线程的信息记录在线程控制块中。

多线程OS中的进程属性

通常在多线程OS中的进程都包含了多个线程,并为它们提供资源。OS支持在一个进程中的多个线程能并发执行,但此时的进程就不再作为一个执行的实体。多线程OS中的进程有以下属性:

(1) 进程是一个可拥有资源的基本单位。

(2) 多个线程可并发执行。

(3) 进程已不是可执行的实体。

线程的类型

用户态线程

用函数库来实现线程。这个线程库,是位于用户空间的。

• 对操作系统来说,用户级线程具有不可见性,也称透明性。

• 应用程序可以自己定制线程调度算法。

• 同一个进程的这些线程只能占用一个核,所以做不到并行加速。

内核态线程

• 内核里就需要有用来记录系统里所有线程的线程表。当需要创建一个新线程的时候,就需要进行一个系统调用,然后由操作系统进行线程表的更新。

• 可以像调度多个进程一样,把这些线程放在好几个 CPU 核心上,做到实际上的并行。(假如线程 A 阻塞了,与他同属一个进程的线程不会被阻塞)

• 操作系统从用户态到内核态的转变是有开销的,所以内核级线程切换的代价要比用户级线程大。

• 线程表是存放在操作系统固定的表格空间或者堆栈空间里,所以内核级线程的数量是有限的,扩展性比不上用户级线程。

扩展

协程 (coroutine)

一种用户态的轻量级线程,它不依赖操作系统的线程或进程调度,而是由应用程序自己来调度协

程的执行。协程之间的切换代价非常小,可以实现高效的并发和异步编程。协程的实现方式有多种,常见的有对称协程和非对称协程。协程的使用场景主要是在需要高效的异步编程、高并发处理和任务调度的应用程序中,例如网络通信、爬虫、游戏等领域。

纤程 (Fiber)

纤程是一种最轻量化的线程(lightweight threads)。它是一种用户态线程(userthread),让应用程式可以独立决定自己的线程要如何运作。它可以在一个线程内并发执行多个协程,从而提高程序的并发性能。Java 纤程的实现方式通常是利用协程调度器来管理多个协程的执行,而协程之间的切换则由协程调度器负责。


相关文章
|
6月前
|
Java 开发者
奇迹时刻!探索 Java 多线程的奇幻之旅:Thread 类和 Runnable 接口的惊人对决
【8月更文挑战第13天】Java的多线程特性能显著提升程序性能与响应性。本文通过示例代码详细解析了两种核心实现方式:Thread类与Runnable接口。Thread类适用于简单场景,直接定义线程行为;Runnable接口则更适合复杂的项目结构,尤其在需要继承其他类时,能保持代码的清晰与模块化。理解两者差异有助于开发者在实际应用中做出合理选择,构建高效稳定的多线程程序。
76 7
|
6月前
|
Go 调度 开发者
[go 面试] 深入理解进程、线程和协程的概念及区别
[go 面试] 深入理解进程、线程和协程的概念及区别
|
2月前
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
82 4
|
3月前
|
Java C# Python
线程等待(Thread Sleep)
线程等待是多线程编程中的一种同步机制,通过暂停当前线程的执行,让出CPU时间给其他线程。常用于需要程序暂停或等待其他线程完成操作的场景。不同语言中实现方式各异,如Java的`Thread.sleep(1000)`、C#的`Thread.Sleep(1000)`和Python的`time.sleep(1)`。使用时需注意避免死锁,并考虑其对程序响应性的影响。
111 8
|
2月前
|
Java 程序员 调度
【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)
创建线程的五种方式,Thread常见方法(守护进程.setDaemon() ,isAlive),start和run方法的区别,如何提前终止一个线程,标志位,isinterrupted,变量捕获
|
2月前
|
安全 Java API
【JavaEE】多线程编程引入——认识Thread类
Thread类,Thread中的run方法,在编程中怎么调度多线程
|
4月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
66 3
|
4月前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
92 2
|
4月前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
68 2
|
4月前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
70 1