【问题标题】:Semaphore example in CC中的信号量示例
【发布时间】:2015-12-14 10:18:17
【问题描述】:

我正在尝试在C 中制作一个简单的信号量示例,其中有两个 while 循环,将使用两个不同的进程在没有线程的情况下产生这个结果:

abcd
abcd
abcd
abcd

由于我不能使用 pthread,我尝试创建常用的 signal()wait() 方法,但由于某些原因,在我的 signal 方法中的 wakeup 调用中出现错误。

#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)

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

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

如果我从 wakeup 中删除 p 参数,那么像 PROT_READ 这样的变量会由于某种原因变得未声明。

附:代码来自本站。

【问题讨论】:

  • signal() 是 c 标准库的一部分,wait() 是 POSIX 的一部分。 不要调用自己的函数signal()wait()

标签: c process synchronization fork semaphore


【解决方案1】:

我不会写完整的东西,但这里有一个更好的方法来解决这个问题。

  1. 使用 2 个信号量。
  2. 当信号量 1 为高时运行第一个进程
  3. 当信号量 2 为高时运行第二个进程
  4. 在第 1 个进程的临界区开始时,将第 2 个信号量设为低电平,使第 2 个进程无法使用该资源
  5. 在第一个进程的关键部分结束时,使第二个信号量 = 1 和第一个信号量 = 0
  6. 对第二个过程完全相反,即声明 sem1 = 0,结束 sem1 = 1,sem2 = 0。

这可能会解决问题。永远不要使用signal,而是使用sigaction

【讨论】:

  • 如果你的意思是这样的话,它没有用(postimg.org/image/t0nra8315
  • 编辑:我将信号量从指针转换为整数并将它们打印出来,但问题是它们的值非常奇怪,每次都在变化。那么,当它的值为 -2223242 或类似的值时,我该怎么说 child=1 呢? (postimg.org/image/kskxqu4pz)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 1970-01-01
  • 2011-09-11
  • 1970-01-01
相关资源
最近更新 更多