什么孩子不从父母那里继承信号量调整(semop(2))呢?

时间:2015-12-24 12:13:51

标签: c unix ipc semaphore

fork(doc)中的这一行引起了我的注意:

  • 孩子不会从其父级继承信号量调整(semop(2))。

这是什么意思?

此程序(下面的代码)永远不会打印“结束(孩子)”:

 #define SVID_SOURCE 1
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/ipc.h>
 #include <sys/sem.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>

 int main(int argc, char **argv) {

   struct sembuf operation;
   int semid = semget (getpid(), 1, 0666 | IPC_CREAT);
   semctl (semid, 0, SETVAL, 1); 

   if (fork() == 0) {
      sleep(1); // Let the father do semop()
      operation.sem_num = 0;
      operation.sem_op = -1;
      operation.sem_flg = 0;
      semop (semid, &operation, 1);
      printf("End (child).\n"); 
      exit(0);
   }

   operation.sem_num = 0;
   operation.sem_op = -1;
   operation.sem_flg = 0;
   semop (semid, &operation, 1);
   wait (NULL);
   printf("The end.\n");

   return 0;
 }

1 个答案:

答案 0 :(得分:3)

首先,有两个独立的信号量子系统:旧式System V信号量和POSIX信号量。不要因为两者都是POSIX的一部分而感到困惑。与问题相关的是System V信号量。

semop(2)系统调用是用于操作系统V信号量集中的值的系统调用。通过此函数修改信号量集的过程可以通过在参数中包含特定标志(由SEM_UNDO表示)在进程退出时自动撤消的方式执行。这会导致一组&#34;信号量调整&#34;因为该信号量设置为与该过程相关联。这些调整不是通过fork继承的,这是有道理的,因为如果它们被继承,则撤销将执行两次 - 一次是在子进程退出时,一次是在父进程退出时。

POSIX信号量通常被认为是提供更好的API,通常它们应该比系统V信号量更受欢迎,但了解这两者是有帮助的。