为什么信号灯不起作用? [英] why is the semaphore not working?

查看:98
本文介绍了为什么信号灯不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

using namespace std;

int main(int argc, char *argv[]){
  int pshared = 1;
  unsigned int value = 0;
  sem_t sem_name;
  sem_init(&sem_name, pshared, value);

  int parentpid = getpid();
  pid_t  pid = fork();

  if (parentpid == getpid()){
    cout << "parent id= " << getpid() << endl;
    sem_wait(&sem_name);
    cout << "child is done." << endl;
  }

  if (parentpid != getpid()){
    cout << "child id= " << getpid() << endl;
    for (int i = 0; i < 10; i++)
      cout << i << endl;

    sem_post(&sem_name);
} 
  sleep(4);
  return 0; 
}

结果应为:

parent id 123456.
child id 123457.
0
1
2
3
4
5
6
7
8
9
child is done.

程序退出,但从不发出信号.

Program exits, but instead it never signals the semaphore.

推荐答案

来自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.

这篇关于为什么信号灯不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆