当前位置: 首页 > 知识库问答 >
问题:

将posix信号量数组分配给共享内存

梁丘波鸿
2023-03-14
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]部分时,我得到了一个分段错误。我在其他地方读到过,不应该创建指向信号量的指针,但是当我没有创建并尝试&sem=addr时,我遇到了一个关于需要lvalue的错误。任何帮助都将不胜感激。

共有1个答案

陶征
2023-03-14

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

而且,与其使用指针数组,为什么不简单地映射整个数组,而不使用指针:

家长:

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, ...);
 类似资料:
  • 我在编写一些简单的代码来自学信号量和POSIX共享内存时遇到了问题。 其思想是一个程序,即服务器,打开共享内存并向其中写入一个结构(包含信号量和数组)。然后它等待输入,输入之后信号量递增。 同时,客户端打开共享内存,等待信号量,在服务器增加信号量之后,读取结构。 服务器似乎工作正常,但是我在客户端的函数处立即遇到了一个segfault(甚至在服务器增加它之前)。我想不出哪里出了问题。 服务器代码:

  • 我想创建一个共享内存和信号量的C程序。应该有两个子进程。两个孩子都有一个不同的int数。然后有一个目标号码,应该写在共享内存中。现在两个孩子都应该从进球数中减去他们的数字,直到进球数低于或等于0。我不希望出现比赛条件。这就是为什么我尝试使用信号量。但对我没用。下面是我的代码:

  • 我有两个使用System V共享内存进行通信的程序。 这两个程序都正常工作,但我想添加命名信号量以避免竞争条件。 我尝试了以下方法: 没有信号量,程序可以工作,但有了信号量,共享内存中不会写入任何内容。我做错了什么?当我使用System V共享内存时,是否可能使用这些信号量?