我们都知道,进程是运转中的程序,是为了在CPU上实现多道编程而发明的一个概念。但是进程在一个时间只能干一件事情,如果想要同时干两件或者多件事情,例如同时看两场电影,我们自然会想到传说中的分身术,就像孙悟空那样可以变出多个真身。虽然我们在现实中无法分身,但进程却可以办到,办法就是线程。线程就是我们为了让一个进程能够同时干多件事情而发明的“分身术”。

一、线程基础

1、线程概念

  线程是进程的“分身”,是进程里的一个执行上下文或执行序列。of course,一个进程可以同时拥有多个执行序列。这就像舞台,舞台上可以有多个演员同时出场,而这些演员和舞台就构成了一出戏。类比进程和线程,每个演员是一个线程,舞台是地址空间,这样同一个地址空间中的所有线程就构成了进程。在线程模式下,一个进程至少有一个线程,也可以有多个线程,如下图所示:
线程基础与线程同步
  将进程分解为线程可以有效地利用多处理器和多核计算机。例如,当我们使用Microsoft Word时,实际上是打开了多个线程。这些线程一个负责显示,一个负责接收输入,一个定时进行存盘…这些线程一起运转,让我们感觉到输入和显示同时发生,而不用键入一些字符等待一会儿才显示到屏幕上。在不经意间,Word还能定期自动保存。

2、线程管理

  由于线程间共享一个进程空间,因此,许多资源是共享的(这部分资源不需要存放在线程控制块中)。但又因为线程是不同的执行序列,总会有些不能共享的资源。一般情况下,统一进程内的线程间共享和独享资源的划分如下表所示:
线程基础与线程同步

3、线程模型

  现代操作系统结合了用户态和内核态的线程模型,其中用户态的执行系统负责进程内部在非阻塞时的切换,而内核态的操作系统则负责阻塞线程的切换,即同时实现内核态和用户态线程管理。其中,内核态线程数量极少,而用户态线程数量较多。每个内核态线程可以服务一个或多个用户态线程。换句话说,用户态线程会被多路复用到内核态线程上。

4、多线程的关系

  推出线程模型的目的就是实现进程级并发,因为在一个进程中通常会出现多个线程。多个线程共享一个舞台,时而交互,时而独舞。但是,共享一个舞台会带来不必要的麻烦,这些麻烦归结到下面两个根本问题:

  • 线程之间如何通信?

  • 线程之间如何同步?

二、线程同步

1、同步的原因和目的

线程基础与线程同步
  出现上述问题原因在于两点:一是线程之间共享的全局变量二是线程之间的相对执行顺序是不确定的。针对第一点,如果所有资源都不共享,那就违背了进程和线程设计的初衷:资源共享、提高资源利用率。针对第二点,需要让线程之间的相对执行顺序在需要的时候可以确定。

2、同步的方式

  • 竞争:两个或多个线程争相执行同一段代码或访问同一资源的现象。

  • 临界区:可能造成竞争的共享代码段或资源。

  • 互斥:在任何时刻都能有一个线程在临界区中的现象。(一次只有一个人使用共享资源,其他人皆排除在外

【锁】:

  锁有两个基本操作:上锁和解锁。很容易理解,上锁就是将锁锁上,其他人进不来;解锁就是你做的事情做完了,将锁打开,别的人可以进去了。解锁只有一个步骤那就是打开锁,而上锁有两个步骤:一是等待锁达到打开状态,二是获得锁并锁上。显然,上锁的两个操作应该是原子操作,不能分开。
线程基础与线程同步
【信号量】:

  信号量(Semaphore)是一个计数器,其取值为当前累积的信号数量。它支持两个操作:加法操作up和减法操作down。执行down减法操作时,请求该信号量的一个线程会被挂起;而执行up加法操作时,会叫醒一个在该信号量上面等待的线程。down和up操作在历史上被称为P和V操作,是操作系统中最重要的同步原语的两个基本操作。

  有些房间,可以同时容纳n个人,比如厨房。也就是说,如果人数大于n,多出来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用。这时的解决方法,就是在门口挂n把钥匙。进去的人就取一把钥匙,出来时再把钥匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法就叫做"信号量",用来保证多个线程不会互相冲突。
线程基础与线程同步
转自:https://www.cnblogs.com/edisonchou/p/5037403.html

相关文章: