C中的信号量示例

时间:2015-12-14 10:18:17

标签: c process synchronization fork semaphore

我试图在C中创建一个简单的信号量示例,其中有两个while循环,将使用两个不同的进程生成没有线程的结果:

abcd
abcd
abcd
abcd

由于我无法使用pthread,因此我尝试使用常见的signal()wait()方法,但由于某些原因,我在wakeup内的signal调用中出现错误方法。

#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>

wait(sem_t *s)
{
    s=s-1;
    if (s<0) 
        block(); // add process to queue
}

signal(sem_t *s)
{
    s=s+1;
    if (s<=0) 
        wakeup(p); // remove process p from queue
}

init(sem_t *s , int v)
{
    s=v;
}

void main(void)
{
  int i;
  // place semaphore in shared memory
  sem_t *child_sem = mmap(NULL,sizeof(*child_sem),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
  sem_t *parent_sem = mmap(NULL,sizeof(*parent_sem),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);

  init(child_sem, 1);  // create child semaphore
  init(parent_sem, 1); // create parent semaphore

  if (fork())
  {
      for (i = 0; i < 10; i++)
      {
           if (wait(child_sem) < 0)
                perror("sem_wait");
           printf("ab");
           if (signal(parent_sem) < 0)
                perror("sem_post");
           sleep(1); // required to maintain thread order
      }
  }
  else
  {
      for (i = 0; i < 10; i++)
      { // parent starts waiting
          if (wait(parent_sem) < 0) 
                perror("sem_wait");
          printf("cd\n");
          if (signal(child_sem) < 0)
                perror("sem_post");
      }
  }
}

输出:

[Error] In function 'signal':
[Error] 'p' undeclared (first use in this function)

问题是如何在唤醒呼叫中输入进程? 我应该在方法中使用pid=fork()吗?

我应该在signal方法中使用额外的参数但会是什么样的? pid p

如果我从wakeup中移除了p参数,那么PROT_READ之类的变量由于某种原因而变为未声明。

P.S。代码来自这个网站。

1 个答案:

答案 0 :(得分:1)

我不会写整篇文章,但这是解决这个问题的更好方法。

  1. 使用2个信号量。
  2. 当信号量1为高时运行第一个进程
  3. 当信号量2为高时运行第二个过程
  4. 在第一个过程的关键部分开始时,使第二个信号量变低,以便第二个过程不能使用该资源
  5. 在第一个过程的关键部分结束时,使第二个信号量= 1,第一个信号量= 0
  6. 对第二个过程完全相反,即声明sem1 = 0,结束sem1 = 1,sem2 = 0.
  7. 这可以解决问题。切勿使用signal代替sigaction