线程/进程 同步 死锁 饥饿

来源:互联网 发布:weblogic新建域 linux 编辑:程序博客网 时间:2024/04/29 16:21

1。为什么要进行线程/进程间的同步?

因为存在多个线程或者进程需要访问相同的资源。如果不进行同步,可能导致错误发生。比如因读写的不同步造成的数据错误,或者死锁的出现等,让系统和数据进入到一种错误或者不稳定的状态。

 

2。使用了多线程就必须要进行同步么?

大部分情况下是这样,但也不能绝对。 因为需要进行同步的情况需要满足两个条件:

a.存在多个线程/进程

b.多个线程/进程之间会相互的竞争资源

如果只是存在多个线程/进程,但只见并没有竟让共有资源,那也没必要进行同步。 如线程内的局部变量等数据

 

 

3.进行同步的机制都有什么?

比如加互斥锁,临界区,信号量等。

互斥锁: 一次只允许一个线程进入共享区域,在离开共享区域时释放锁。

临界区: 类似互斥锁

信号量: 维护一个数,允许特定数量的线程进入

 

4。什么是原子操作。

原子操作就是一组不可分离的操作。应该把它视为一个整体,要么全部成功,要么全部失败,不会出现部分成功,部分失败的现象。而且原子操作执行中间不会被打断。

 

5. 原子操作的不会被打断是什么意思,是说线程不会被切换么?

不是的。

有的原子操作是由处理器本身所支持的。 如一条指令本身肯定是一个原子操作。

但有的原子操作是一个执行块,这时在这个执行块中间,是非常有可能发生线程间的切换的。

有时候,一条高级语言的语句可能会被编译成好几条对应的汇编语句(机器语句) 如 c = a+b; 很有可能还没有算出c的结果线程就被切换了。

 

 但发生线程间的切换并不意味着数据就可以被其他的线程访问。因为我们可以通过加锁的办法,让其他线程不能进入到执行块内部。这样其他线程虽然获得了CPU时间,但如果要访问执行块,只有等待,别的什么也做不了。数据还是安全的。

 

6. 锁和原子操作是一个概念么。

当然不是。

原子操作是一个不可被分割的单个或者多个操作。

锁是一种机制,让我们来协调各个线程,来实现原子操作。

感觉原子操作和锁是一个相辅相成的概念。

原子操作 分为物理的  和 软件实现的两种

物理的比如一条单独的汇编语句。

软件实现的往往依赖于锁

 

锁又分为硬件级别的和软件模拟的锁。

软件模拟的锁本身也是内存中的一堆数据,和别的数据没什么区别,也会被多个线程同时访问。所以纯的软件锁是没有概念的。软件模拟的锁需要硬件提供的物理原子操作的支持。如Intel CPU 就有一条指令: 交换两个寄存器的值。

 

软件锁的一种,旋锁,就是依赖于上面这条特殊的物理原子操作指令来实现的

 

当然,现在的处理器一般也都提供了很多物理级别的原子操作。

 

7. 什么是死锁。

死锁就是系统进入到一种阻塞的,无法移动的状态。用“有限状态机”的概念来说,所有状态都不能迁移到下一个状态了。

如在一个单轨的铁路上,两条火车向不同的方向开。 谁也动不了了

 

8. 为什么会发生死锁

死锁一般都是由于对共享资源的竞争引起的。 但对共享资源的竞争又不一定就会发生死锁。 死锁的发生必须同时满足四个条件:互斥,持有/等待,非抢占, 形成等待环。

① Mutual exclusion condition: a resource that cannot be used by more than one process at a time

② Hold and wait condition: processes already holding resources may request new resources

③ No preemption condition: No resource can be forcibly removed from a process holding it, resources can be released only by the explicit action of the process

④ Circular wait condition: two or more processes form a circular chain where each process waits for a resource that the next process in the chain holds

 

形成死锁最直观的现象就是出现等待环

 

9. 什么是活锁

 

活锁和死锁很像似。 只是活锁的状态可以发生改变。不过虽然状态可以改变,却没有实质的进展。

比如两个人在一个很宅的胡同里。 一次只能并排过两个人。 两人比较礼貌,都要给对方让路。 结果一起要么让到左边,要么让到右边,结果仍然是谁也过不去。 类似于原地踏步或者震荡状态。

 

活锁一般是由于对死锁的不正确处理引起的。由于处于死锁中的多个线程同时采取了行动。 而避免的方法也是只让一个线程释放资源。

 

 

A livelock is similar to a deadlock, except that the states of the processes involved in the livelock constantly change with regard to one another, none progressing.Livelock is a special case of resource starvation; the general definition only states that a specific process is not progressing.

 

Livelock is a risk with some algorithms that detect and recover from deadlock. If more than one process takes action, the deadlock detection algorithm can repeatedly trigger. This can be avoided by ensuring that only one process (chosen randomly or by priority) takes action

 

10. 什么是饿死。

饿死(starvation) 是一个线程长时间得不到需要的资源而不能执行的现象。 有人饿死并不代表着出现了死锁。

很有可能系统还能很好的进行。

所以,没有出现死锁并不能就认为系统是完好的。还要保证没有出现饿死的现象。

避免饿死就应该是采用队列的方式,保证每个人都有机会获得请求的资源。 当然实现方式可以很多个变化,比如优先级,时间片,等,都是“队列”的特殊形式

 

 

原创粉丝点击