使用system-v信号量进行父子同步

时间:2016-09-16 12:42:03

标签: c ipc semaphore

我有一个函数在循环中通过char打印char。我尝试做的是同步父进程和子进程,以便每个进程打印一行而不会有其他干扰。我试图用信号量做到这一点。

这是我的代码:

int main() {   
  int i, sem;   
  struct sembuf u   = {0, 1, 0};   
  struct sembuf d = {0 -1, 0};   
  sem = semget(IPC_PRIVATE, 1, 0600);   
  semctl(sem, 0, SETVAL, 1);

  if (!fork())   {
      for (i=0;i<10;i++){
          semop(sem, &d, 1)) < 0)
          print_char_by_char("hello\n");
          semop(sem, &u, 1);
      }



  } else {
      for (i=0;i<10;i++){
          semop(sem, &d, 1);
          print_char_by_char("world\n");
          semop(sem, &u, 1);
      }


      semctl(sem, 0, IPC_RMID);
  }
  return 0; 
}

所以这不起作用,打印件出现乱码,我真的不确定原因。如果我像这样检查semop

if((x = semop(sem, &down, 1)) < 0)
    perror("semop");

我正在semop: File too large

1 个答案:

答案 0 :(得分:0)

根据man semop

  

EFBIG:对于某些操作,sem_num的值小于0或   reater大于或等于集合中信号量的数量。

然后,在不知道你的print_char_by_char功能如何的情况下,我们无法知道你为什么会出现乱码?请记住printf和其他人都是缓冲的,所以你应该使用下面的fflush ,或直接使用write

顺便说一句,我试图执行你的代码(我在下面写的)并且我没有任何问题(因为你没有指定你期望的输出)如果我删除

semctl(sem, 0, IPC_RMID);

也许你放错地方(应该在return之前,否则先完成的人将删除信号量集,我猜)

<强> CODE

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/sem.h>

void error_handler(const char *msg)
{
    perror(msg);
    exit(EXIT_FAILURE);
}

int main(int argc, const char **argv)
{
    if (argc != 1)
    {
        fprintf(stderr, "Usage: %s <no arguments>\n", argv[0]);
        return EXIT_FAILURE;
    }

    int i, sem;
    struct sembuf u = {0, 1, 0};
    struct sembuf d = {0, -1, 0};
    sem = semget(IPC_PRIVATE, 1, 0600);
    semctl(sem, 0, SETVAL, 1);

    if (!fork())
    {
        for (i = 0; i < 10; i++)
        {
            if (semop(sem, &d, 1) == -1)
                error_handler("main | semop [d - father]\n");
            if (write(STDOUT_FILENO, "hello\n", 7) == -1)
                error_handler("main | write [hello]\n");
            if (semop(sem, &u, 1) == -1)
                error_handler("main | semop [u - father]\n");
        }
    } else {
        for (i = 0; i < 10; i++)
        {
            if (semop(sem, &d, 1) == -1)
                error_handler("main | semop [d - child]\n");
            if (write(STDOUT_FILENO, "world\n", 7) == -1)
                error_handler("main | write [world]\n");
            if (semop(sem, &u, 1) == -1)
                error_handler("main | semop [u - child]\n");
        }

        // semctl(sem, 0, IPC_RMID);
    }

    return EXIT_SUCCESS;
}

<强>输出

world
world
world
world
world
world
world
world
world
world
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello

相反,如果你想在父子关系中同步两个进程(这听起来很奇怪......)我建议你共享内存和POSIX信号量