(1)SIG_IGN   

这个符号表示忽略该信号。

 

 

 

 


 

什么是TSL指令?(也就是Peterson互斥算法)

TSL指令是一种需要硬件支持的方案。许多计算机,特别是那些为多处理机设计的计算机,都有一条指令叫做测试并上锁(TSL)。

其工作如下所述:它将一个存储器字读到一个寄存器中,然后在该内存地址上存一个非零值。

读数和写数操作保证是不可分割的——即该指令结束之前其他处理机均不允许访问该存储器字。

执行TSL指令的CPU将锁住内存总线以禁止其他CPU在本指令结束之前访问内存。

 

为了使用TSL指令,我们必须用一个共享变量lock来协调对共享内存的访问。

当lock为0时,任何进程都可以使用TSL指令将其置为1并读写共享内存。当操作结束时,进程用一条普通的MOVE指令将lock重新置为0。

这条指令如何被用来防止两个进程同时进入临界区呢?解决方案示于图2-10。其中示出了使用四条指令的汇编语言例程。

第一条指令将lock原来的值拷贝到寄存器中并将lock置为1,随后这个原先的值与0相比较。如果它非零,则说明先前已被上锁,则程序将回到开头并再次测试。经过或长或短的一段时间后它将变成0(当前处于临界区中的进程退出临界区时),于是子例程返回,并上锁。清除这个锁很简单,程序只需将0存入lock即可,不需要特殊的指令。

enter_region:
tsl register,lock |复制lock到寄存器,并将lock置为1
cmp register,#0 | lock等于0吗?
jne enter_region |如果不等于0,已上锁,再次循环
ret |返回调用程序,进入临界区
leave_region:
move lock , #0 |置lock为0
ret |返回调用程序 

图2-10 用TSL指令上锁和清除锁

现在就有一种很明确的解法了。

①进程在进入临界区之前先调用enter_region。这将导致忙等待,直到锁空闲为止。

②随后它获得锁变量并返回。在进程从临界区返回时它调用leave_region,这将把lock置为0。

 

与临界区问题的所有解法一样,进程必须在正确的时间调用enter_region和leave_region,解法才能奏效。如果一个进程有欺诈行为,则互斥将会失败。

 


进程互斥--硬件实现方法

解决竞争的方案必须满足的4个条件:

  1. 任何两个进程不能同时处于临界区
  2. 不应该对CPU的速度和数目做任何假设
  3. 临界区外的进程不应该阻塞其他进程
  4. 不得使进程在临界区外无休止的等待

 

1、中断屏蔽方法

单处理机:在单处理机中,并发进程不能重叠,只能交替,操作系统通过中断来实现进程的交替,那么就会存在一个问题,当一个进程A运行到临界区时发生了中断,另一个进程B运行,进程B也可以运行临界区代码,这样就改变了临界资源,当进程A再接着中断的位置运行时相关数据有可能已经被进程B修改,出现错误。

      这个问题可以通过禁用中断来解决,禁用中断和启用中断都是原语操作。通过这个方法来实现互斥如下:

while(true)
{
/* 禁用中断 */
/* 临界区 */
/* 启用中断 */
/* 其余部分 */
}

 

利用“开/关中断指令”实现
优点:简单、高效
缺点:不适用于多处理机;由于开关中断权限很大,只适合操作系统的内核进程,不适用于用户进程;违背让权等待原则。

2、TestAndSet指令(TS、TestAndSetLock、TSL)

 

 

TSL指令使用硬件实现,执行过程中不允许被中断

TestAndSet实现逻辑

//布尔型共享变量lock表示当前临界区是否被加锁
//true表示已加锁
bool TestAndSet(bool *lock){
    bool old = *lock;   //old用于存放lock原来的值
    *lock = true;     //无论之前是否已加锁,都将lock设为true
    return old;
}

TSL实现互斥

while(TestAndSet(&lock)){    //检查并上锁
    //临界区代码
    lock = false;    //解锁
    //剩余区代码
}

优点:实现简单;适用于多处理机环境
缺点:违背让权等待原则

 

多处理机

①在多处理机配置中,几个处理器共享内存,处理器间的行为是对等的,处理器之间没有支持互斥的中断机制。

②在硬件级别上,对存储单元的访问排斥对相同单元的其他访问。

基于这一点,处理器的设计者提出了一些机器指令,用于保证两个动作的原子性,即某一时刻只能有一个临界区代码访问临界资源

两种最常见的指令是:比较和交换指令、交换指令。

3、Swap指令(Exchange、XCHG指令)

Swap指令使用硬件实现,执行过程中部允许中断。

Swap实现逻辑

Swap(bool *a, bool *b){
    bool temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

Swap实现互斥

bool old = true;
while(old==true){
    Swap(&lock,&old);
}
//临界区代码
lock = false;
//剩余区代码



进程互斥 软件实现方法

1、单标志法
算法思想:两个进程在访问完临界区后,会把使用临界区的权限交给另一个进程。每个进程进入临界区的权限只能被另一个进程赋予。
违背原则:空闲让进、让权等待
2、双标识先检查法
算法思想:设置一个布尔型数组flag[],数组中各元素用来标记进程想进入临界区的意愿,true表示想要进入。每个进程在进入临界区之前先检查当前有没有别的进程想进入临界区,如果没有,则把自身的flag设为true,之后开始访问临界区。
违背原则:忙则等待、让权等待
3、双标识后检查法
算法思想:双标识后检查法的改进版。前一个算法的问题是先检查后上锁,但是这两个操作无法一气呵成,因此导致了两个进程可能同时进入临界区。所以改进为先上锁后检查来避免上述问题。

违背原则:空闲让进、有限等待、让权等待
4、Peterson算法
算法思想:双标识后检查法中,两个进程都争着想要进入临界区,谁也不让谁,最后都无法进入临界区。Peterson算法使用了一种主动让对方先使用临界区的思想。
违背原则:让权等待

原文链接:

Dekker算法


 


 

参考资料:

1.进程管理报告:

https://wenku.baidu.com/view/136b7db8f9c75fbfc77da26925c52cc58bd6909c.html