child does not inherit semaphore adjustments from its parent (semop(2)) 是什么意思?

What child does not inherit semaphore adjustments from its parent (semop(2)) mean?

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

这是什么意思?

这个程序(下面的代码)永远不会打印 "End (child)" :

 #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;
 }

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

semop(2) 系统调用是用于操纵系统 V 信号量集中的值的系统调用。通过此函数修改信号量集的进程可以通过在参数中包含一个特定标志(由 SEM_UNDO 表示)来在进程退出时自动撤消。这会导致该信号量集的一组 "semaphore adjustments" 与进程相关联。正是这些调整不会通过分叉继承,这是有道理的,因为如果它们被继承,那么撤消将执行两次——一次是在子进程退出时,一次是在父进程退出时。

POSIX 信号量通常被认为可以提供更好的 API,通常它们应该优于系统 V 信号量,但了解两者是有帮助的。