【问题标题】:Assigning an array of posix semaphores to shared memory将 posix 信号量数组分配给共享内存
【发布时间】:2023-04-11 03:09:02
【问题描述】:

我想将一组未命名的信号量写入共享内存,这样我就可以在分叉的进程中访问它们。到目前为止,这是我所拥有的:

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

int num_process = atoi(argv[1]);
int i = 0;

int ppid = getpid();
void *addr;

int numsems = 512;
int object_size = numsems * sizeof(sem_t);

printf("declaring semaphores\n");
sem_t *sem[numsems];

//create shared memory and check that it worked
printf("opening shared memory\n");
int shmem_fd = shm_open("/my_shmem", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);

if(shmem_fd == -1){
    perror("Can't open shmem object");
    exit(-1);
}

//truncate memory object
if(ftruncate(shmem_fd, object_size) == -1){
    perror("failed to resize shmem object");
    exit(-1);
}

addr = mmap(NULL, object_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmem_fd, 0);

if(MAP_FAILED == addr){
    perror("Map failed");
    exit(-1);
}

//store the semaphores at the start
printf("initializing semaphores\n");

for(i = 0; i<numsems; i++){
    sem[i] = addr + i*sizeof(sem_t);
    if(sem_init(sem[i], 1, 0) == -1){
            perror("sem_init failed");
            exit(-1);
    }
}

//create children
while((getpid() == ppid) && (i < num_process)){


    switch(fork()){
    case -1:
    printf("fork %d failed\n", i);
    break;

    case 0:
    //child process
    printf("child created\n");
    child_program( sem, numsems);
    printf("child done\n");
    break;

    default: //parent continues on to create next child
    break;

    }
i++;
}
}

编译得很好,但是当我尝试运行它时,当它到达sem_t *sem[numsems] 部分时会出现分段错误。我在其他地方读到过你不应该创建指向信号量的指针,但是当我没有尝试&amp;sem = addr 时,我得到了一个关于需要左值的错误。任何帮助将不胜感激。

【问题讨论】:

  • 不确定你是否在删除示例时错过了它,但变量 i 必须在进入 fork 循环之前设置为零,否则它不会运行。除此之外,它对我有用,尽管我没有以任何方式操纵信号量。

标签: c posix shared-memory semaphore


【解决方案1】:

首先,为什么不在父进程中创建(和映射)共享内存段,然后在子进程中打开呢?

另外,为什么不使用指针数组,而不是简单地映射整个数组,而不使用指针:

家长:

sem_t *sem;

shm_open("/my_shmem", O_CREAT | O_RDWR ...);

sem = mmap(NULL, object_size, ...);

孩子:

semt_t *sem;

shm_open("/my_shmem", O_RDWR, 0);

sem = mmap(NULL, object_size, ...);

【讨论】:

  • 哎呀,我在我的程序中有它,但是当我复制它时,我试图清理它,所以我一定是丢失了
  • 那么我将如何等待某个信号量?说第 100 个?
  • 共享内存文件由父进程打开然后通过开放描述符继承传递给其子进程的一个优点是它可以在打开后立即取消链接。因此,如果主程序崩溃,共享内存块将在所有子进程完成后自动删除(无论是否正常),否则它将持续存在直到手动删除。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-26
  • 2020-09-01
  • 2023-03-19
  • 1970-01-01
  • 2010-11-27
  • 1970-01-01
  • 2018-06-21
相关资源
最近更新 更多