【问题标题】:parent-child sync with system-v semaphores使用 system-v 信号量进行父子同步
【发布时间】:2017-01-24 16:51:09
【问题描述】:

我有一个函数可以在循环中逐个字符地打印一些东西。我想要做的是同步父进程和子进程,以便每个进程都打印一行,而不会受到其他进程的干扰。我正在尝试使用信号量来做到这一点。

这是我的代码:

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

【问题讨论】:

    标签: c ipc semaphore


    【解决方案1】:

    根据man semop

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

    那么,在不知道你的print_char_by_char函数怎么样的情况下,我们无法知道为什么会出现乱码打印(记住printf和其他都是有缓冲的,所以接下来应该使用fflush,或者直接使用@987654325 @ 代替。

    顺便说一句,我尝试执行你的代码(我在下面写的),如果我删除

    ,我没有任何问题(因为你没有指定你期望的输出)
    semctl(sem, 0, IPC_RMID);
    

    也许你放错了位置(应该在return之前,否则我猜第一个完成的人会删除信号量集)

    代码

    #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 信号量

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-13
      • 1970-01-01
      • 2014-11-21
      • 1970-01-01
      • 1970-01-01
      • 2012-01-04
      相关资源
      最近更新 更多