1. 什么是线程?线程共享进程的哪些内存空间?线程独有的资源有哪些?
-
线程(Thread):
是程序执行流的最小单元。 -
线程共享进程的内存空间包括:
代码段、数据段、堆空间、以及一些进程级别资源(比如打开文件) -
线程独有的资源有:
线程 ID、当前指令指针(PC)、寄存器集合、栈空间
经典的线程与进程关系图
2. 多个线程与单个线程相比,有哪些优势?(换句话就是什么情况下使用多线程?至少说三点)
- ① 某个操作可能会陷入长时间等待,等待的线程会进入睡眠状态,无法继续执行。多线程执行可以有效利用等待的时间。典型的例子是等待网络响应,这可能要花费数秒甚至数十秒。
- ② 某个操作(常常是计算)会消耗大量时间,如果只有一个线程,程序和用户之间的交互就会中断。多线程可以让一个线程负责交互,另一个线程负责计算。
- ③ 程序逻辑本身就要求并发操作。例如一个多端下载软件(比如迅雷)
- ④ 多 CPU 或 多核计算机,本身具备同时执行多个线程的能力,因此单线程程序无法全面发挥计算机的全部计算能力。
3. 什么是线程调度?什么是时间片?
-
线程调度(Thread Schedule):
操作系统会让这些多线程程序轮流执行,每次仅执行一小段时间(通常是几十到几百毫秒),这样每个线程就“看起来”在同时执行。这样的一个不断在处理器上切换不同线程的行为称之为线程调度。 -
时间片(Time Slice):
处于运行中的线程拥有一段可以执行的时间,这段时间称为时间片(Time Slice)
4. 在线程调度中,线程通常拥有至少三种状态,分别是什么?状态之间如何切换?
- 运行(Running): 此时线程正在执行。
- 就绪(Ready): 此时线程可以立刻运行,但是 CPU 已经被占用。
- 等待(Waiting): 此时线程正在等待某一事件(通常是 I/O 或同步)发生,无法执行。
线程状态切换
5. 线程调度自多任务操作系统问世以来就不断被提出不同的方案和算法,现在主流的调度方式尽管各不相同,但是都有哪两种方案的影子?
- 优先级调度(Priority Schedule)
- 轮转法(Round Robin)
6. 为了避免多个线程同时读写同一个数据而产生不可预料的后果,我们要将各个线程对同一个数据的访问同步
,请解释这里的同步
的含义?
-
同步(Synchronize):
即在一个线程访问数据未结束的时候,其他线程不得对同一个数据进行访问。如此,对数据的访问被原子化了。
7. 同步的最常见方法是什么?比阐述其机制?
- 同步的最常见方法是使用锁(Lock)。
- 锁是一种非强制机制,每一个线程在访问数据或资源之前首先试图获取(Acquire)锁,并在访问结束之后释放(Release)锁。在锁已经被占用的是会试图获取锁时,线程会等待,直到锁重新可用。
8. 在加锁方案中,信号量有什么特点?
- 信号量(Semaphore): 是最简单的一种锁。
- 特点:它只有占有与非占有两种状态,释放者和加锁者可以不是同一线程。
- 也就是说,同一个信号量可以被系统的中一个线程获取后由另一个线程释放。
9. 在加锁方案中,互斥量有什么特点?
- 互斥量(Mutex)和二元信号量很类似,资源仅同时运行一个线程访问。
- 和信号量不同的是,互斥量要求哪个线程获取了互斥量,哪个线程就要负责释放这个锁,其他线程越俎代庖去释放互斥量是无效的。
10. 在加锁方案中,读写锁有什么特点?
- 读写锁(Read-Write Lock):致力于一种更加特点的场合的同步。
- 读写锁有两种获取方式,共享的(Shared) 或 独占的(Esclusive)
- 当锁处于自由的状态时,试图以任何一种方式获取锁都能成功,并将锁置于对应的状态。
- 当锁处于共享状态时,其他的线程以共享的方式获取锁仍然成功,此时这个锁分配给了多个线程。然而,如果其他线程试图以独占的方式获取已经处于共享状态的锁,那么它必须等待锁被所有的线程释放。
- 当锁处于独占状态时,锁将阻止其他任何线程获取该锁,不论它们试图以哪种方式获取。
11. 在加锁方案中,条件变量有什么特点?
- 条件变量(Condition Variable)作为一种同步手段,作用类似于一个栅栏。
- 线程可以有两种操作:①线程可以等待条件变量 ②线程可以唤醒条件变量
- 一个条件变量可以被多个线程等待。
- 线程唤醒条件变量,此时所有等待次条件变量的线程都会被唤醒并继续执行。
12. 对用户来说如果有三个线程在同时执行,对内核来说可能只有一个线程
,你怎么理解这句话?
- 用户实际使用的线程并不是内核线程,而是存在于用户态的用户线程。
13. 对于用户线程和内核线程的线程模型有哪三种?
- 一对一线程模型
- 多对一线程模型
- 多对多线程模型(目前基本是采用这种线程模型)