从伪代码定义信号量

时间:2017-03-26 15:40:42

标签: c semaphore

这是我之前提出的问题:Fork(); method in C: determine order

我现在想学习如何从这个伪代码定义信号量,包括结构和操作。 我只找到了太复杂的信号量定义示例,所以我根本不知道它们。

上一篇文章中的伪代码:

Th1 { display "Hello 1" }
Th2 { display "Hello 2" }
Th3 { display "Hello 3" }

main() {
    Fork(Th1);Fork(Th2);Fork(Th3);
}

1 个答案:

答案 0 :(得分:1)

我不确定您是要尝试定义自己的信号量实现还是要使用POSIX实现。

使用POSIX信号量,您应首先声明一个全局信号量,供您的不同线程使用(在您的情况下,它们似乎是不同的进程),如下所示:

sem_t name_of_your_semaphore;

之后,您需要使用sem_init初始化您的信号量:

sem_init(&name_of_your_semaphore, pshared, initial_value);

其中pshared和initial_value都是int。正如您在sem_init man page中看到的,如果pshared为0,则信号量可以在单个进程中的线程之间共享。如果pshared不为0,则可以跨多个进程共享它。由于您在程序中使用fork系统调用,实际上是在创建不同的进程,因此您应该使用非零的pshared值。 initial_value是您的信号量的初始值。如果将其初始化为1,则将其称为二进制信号量,它可用于提供互斥。如果将其初始化为大于1的值,则它是一个计数信号量,它可用于消费者 - 生产者问题,如您希望在该资源的不同使用者之间管理资源的多个实例。要了解初始值如何影响同步,您必须了解在等待或发信号通知信号时会发生什么。

等待

  1. 将信号量(由initial_value表示)的值减少1。
  2. 检查该值是否小于0.
  3. 如果该值小于0,则将进程置于休眠状态并将其置于信号量队列中。 CPU不再尝试安排此过程,与更天真的忙等待方法相比,这会带来性能提升。
  4. 如果该值大于或等于0,则不会阻止该进程并继续执行。
  5. 信号

    1. 增加信号量的值。
    2. 如果信号量的值小于或等于0,则表示先前在信号量上称为等待的某个进程仍然在其上被阻塞。在这种情况下,我们发出信号通知这个过程,通知它现在可以恢复执行。我们将信号量队列中的第一个进程用于恢复执行。 CPU负责安排它再次运行。
    3. 这就是说,如果你想确保相互排斥,你只需将initial_value设置为1。

      要等待您的信号量,请致电:

      sem_wait(&name_of_your_semaphore);
      

      这将导致上述过程,值减少。如果它为零,则该进程是第一个调用wait的进程,因此它不必等待(它将是第一个尝试访问您尝试保护的资源的进程)。如果该值小于0,则进程将进入休眠状态并置于信号量队列中。

      发信号通知您的信号量(即告诉正在队列中等待它恢复执行的进程):

      sem_post(&name_of_your_semaphore);
      

      上述过程中的结果。

      希望这有帮助。