且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么信号灯不起作用?

更新时间:2023-02-26 18:26:39

来自sem_init的联机帮助页:

如果pshared不为零,则信号量在两个之间共享 流程,并且应位于 共享内存的区域(请参见shm_open(3),mmap(2)和shmget(2)). (由于孩子是由fork(2)创建的 继承其父级的内存映射,它也可以访问该信号量.)可以访问的任何进程 共享内存区域可以使用sem_post(3),sem_wait(3)等对信号量进行操作.

If pshared is nonzero, then the semaphore is shared between processes, and should be located in a region of shared memory (see shm_open(3), mmap(2), and shmget(2)). (Since a child created by fork(2) inherits its parent's memory mappings, it can also access the semaphore.) Any process that can access the shared memory region can operate on the semaphore using sem_post(3), sem_wait(3), etc.

POSIX信号量是堆栈结构.它们不是像文件描述符那样对内核维护的结构进行引用计数的引用.如果要通过两个过程共享POSIX信号量,则需要自己进行共享.

POSIX semaphores are on-the-stack structs. They aren't reference-counted references to a kernel-maintained struct like filedescriptors are. If you want to share a POSIX semaphore with two processes, you need to take care of the sharing part yourself.

这应该有效:

#include <fstream>
#include <iostream>
#include <semaphore.h>
#include <stdio.h>
#include <string>
#include <sysexits.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>


int main(int argc, char *argv[]){
  using namespace std;
  sem_t* semp = (sem_t*)mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED, 0, 0 );
  if ((void*)semp == MAP_FAILED) { perror("mmap");  exit(EX_OSERR); } 

  sem_init(semp, 1 /*shared*/, 0 /*value*/);

  pid_t  pid = fork();
  if(pid < 0) { perror("fork");  exit(EX_OSERR); } 

  if (pid==0){ //parent
    cout << "parent id= " << getpid() << endl;
    sem_wait(semp);
    cout << "child is done." << endl;
  }else { //child
    cout << "child id= " << getpid() << endl;
    for (int i = 0; i < 10; i++)
      cout << i << endl;
    sem_post(semp);
  } 
  return 0; 
}

注意::如果您只想要这种行为,那么waitpid显然是可行的方法.我假设您要测试POSIX信号量.

Note: If you want just this behavior, then waitpid is obviously the way to go. I'm assuming what you want is to test out POSIX semaphores.