信号量的一些内容

信号量S是个整数变量,除了初始化以外,只能通过两个标准原子操作:wait()(P操作)和signal()(V操作)来访问。

wait()的定义:

1 wait(s) {
2     while (S<=0)
3         ;  //no-operation
4     S--;
5 }

signal()的定义:

1 signal(S) {
2     S++;
3 }

因为这两个是原子操作,因此对信号量整型值的修改必须不可分地执行。即当一个进程修改信号量时,不能有其他进程同时修改同一信号量的值。

1. 信号量用法

  信号量通常分为计数信号量和二进制信号量。计数信号量的值域不受限制,为整数;二进制信号

信号量 别名 值域
计数信号量   所有整数
二进制信号量 互斥锁(mutex) 0和1

  可以使用二进制信号量处理多进程的临界问题。设n个进程共享一个信号量mutex,并初始化为1。每个进程的结构:

do {
    wait(mutex);
        // 临界区(critical section)
    signal(mutex);
        // 剩余区(remainder section)
}while(TRUE);

  计数信号量可以用来控制访问具有若干个实例的某种资源。该信号量初始化为可用资源的数量。当每个进程需要使用资源时,需要对该信号量执行wait()(P操作)操作,减少信号量的计数。当进程释放资源时,需要对该信号量执行signal()操作,增加信号量的计数。信号量的计数为0时意味着所有资源都被使用,之后所有需要使用资源的进程将会被阻塞,知道计数大于0。

  也可以使用信号量解决同步问题。例如,有两个并发进程P1有语句S1,P2有语句S2,假设要求在S1执行完后才执行S2,令P1和P2共享一个共同信号量synch,将其初始化为0,

P1中插入语句:

S1;
signal(synch);

P2中插入语句:

wait(synch);
S2;

2. 实现

  以上所定义的信号量也称为自旋锁。自旋锁通常用于多处理器系统中,这样一个线程在一个处理器自旋时,另一个线程可以在另一个处理器上在其临界区执行。

  • 其优点是,进程在等待锁时不进行上下文切换(上下文切换可能需要花费相当长的时间),如果锁的占用时间短,那么自旋锁就有用了;
  • 其缺点是,忙等待(busy waiting)。当一个进程位于其临界区内时,任何其他试图进入临界区的进程都必须在其进入代码中连续地循环。这种连续循环在实际多道程序系统中是个问题,因为这里只有一个处理器为多个进程所共享。忙等待浪费了CPU时钟,而这本可以有效地为其他进程所使用。

  为了克服忙等,可以修改信号量操作wait()和signal()的定义。当一个进程执行wait()操作时, 发现信号量不为正(+),则它必须等待。然而,该进程不是忙等而是阻塞自己,阻塞操作将一个进程放入到与信号量相关的等待队列中,并将该进程的状态切换成等待状态。接着,控制转到CPU调度程序,以选择另一个进程来执行。

  一个被阻塞在等待信号量S上的进程, 可以在其他进程执行signal()操作之后被重新执行。该进程的重新执行使通过wakeup()操作来进行的,该操作将进程从等待状态切换到就绪状态。接着,该进程被放入到就待续队列中,CPU调度算法不同,CPU有可能会也可能不会从正在运行的进程切换到刚刚就绪的进程。

  为了实现此种定义的信号量,信号量的定义如下:

typedef strucet {
  int value;
  struct process *list;
} semaphore;

  每个信号量都有一个整型值和一个进程链表。 当一个进程必须等待信号量时,就加入到进程链表上。 操作signal() 慧聪等待进程链表中取一个进程以唤醒。

  信号量操作wait()如下定义:

wait(semaphore *S) {
  S->value--;
  if (S-> value < 0) {
    add this process to S->list;
    block();
  }
}

  信号量操作signal如下定义:

signal(semaphore *S) {
  S->value++;
  if (S->value <= 0) {
    remove a process P from S->list;
    wakeup(P);
   }
}

  操作block()挂起调用它的进程。操作wakeup(P)重新启动阻塞进程P的执行。这两个操作都是由操作系统作为基本系统调用来提供的。

  注意:在具有忙等的信号量的经典定义下, 信号量的值不可能为负。

 

posted on 2015-12-16 22:08  DrawToy  阅读(1459)  评论(1)    收藏  举报

导航