使用信号量在三个进程之间共享内存

问题描述 投票:0回答:1

进程1派生进程2和3,每个进程将等于其编号的字符写入共享内存。最后一个进程应该读取内存

输出看起来应该像“ read:123”,但我却得到“ read:1”(只有最后一个进程号)

我不知道如何在多个进程中使用共享内存,有帮助吗?

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <zconf.h>
#include <sys/sem.h>
#include <wait.h>

int main(){
    int pid1, pid2, pid3, semid, shmid, n=3;
    semid = semget(1, 1, 0);
    shmid = shmget(2,1024,0666|IPC_CREAT);
    char *number = (char *) shmat(shmid, (void *) 0, 0);
    pid1=getpid();
    pid2=fork();
    pid3=fork();

    if(pid3==0) {
        printf("Process 3 is writing...\n");
        gets(number);
    }
    else if(pid2==0){
        wait(NULL);
        printf("Process 2 is writing...\n");
        gets(number);
    }
    else{
        wait(NULL);
        printf("Process 1 is writing...\n");
        gets(number);
        printf("read: %s\n", number);
    }

}

我只想获取有关多进程内存写入的一些建议。

c unix process semaphore
1个回答
0
投票

这里是固定的答案,其中包含经过修改和简化的程序以及说明。

[创建子进程时,父进程使用的大多数环境都是继承的:共享内存段是自动继承的-您无需运行任何shmat,shmget或shmctl例程。

要读写共享内存段,子进程需要知道相应的地址:它已经有了它,因为在您的代码中它是数字变量。

我在代码中简化了您的示例:

  • 仅两个进程:父级和子级
  • 在流程中不使用gets:流程仅在其中写入一个字母共享内存:父写“ P”,子写“ C”;后孩子退出,父级再次读取共享内存以检查该值是否为孩子写了什么
  • 我添加了很多printf以显示谁是当前进程(父进程或子进程)以及该进程在做什么
  • 就像在您的代码中一样,父子之间没有读写共享内存的同步:这只是一个简化的示例。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <unistd.h>

int main(){
    pid_t pid;
    int shmid;
    char *addr;

    shmid = shmget(2,1024,0666|IPC_CREAT);
    addr = (char *) shmat(shmid, (void *) 0, 0);
    printf("In parent => addr: %p \n", (void *)addr);
    printf("In parent  =>  writing *addr ... \n");
    *addr = 'P';
    printf("In parent  =>  ... writing *addr: done \n");
    printf("In parent  => reading *addr = %c \n", *addr);

    pid = fork();
    if(pid == 0) 
    {
        printf("In child  => PID: %d PPID: %d\n", getpid(), getppid());
        printf("In child  => addr: %p \n", (void *)addr);
        printf("In child  => reading *addr = %c \n", *addr);
        printf("In child  => writing *addr ... \n");
        *addr = 'C';
        printf("In child  => ... writing *addr: done \n");
        printf("In child  => reading *addr = %c \n", *addr);
        printf("In child  => exiting \n");
        exit(EXIT_SUCCESS);
    }
    else if(pid > 0) 
    {
        printf("In parent => PID: %d\n", getpid());
        printf("In parent => waiting for child process to finish ...\n");
        wait(NULL);
        printf("In parent => child process finished.\n");
        printf("In parent  => reading *addr = %c \n", *addr);
    }
    else {
        printf("In parent => unable to create child process.\n");
    }

   printf("In parent => exiting.\n"); 
  return EXIT_SUCCESS;
}

输出示例:

In parent => addr: 0x7fcef5100000 
In parent  =>  writing *addr ... 
In parent  =>  ... writing *addr: done 
In parent  => reading *addr = P 
In parent => PID: 22027
In parent => waiting for child process to finish ...
In child  => PID: 22028 PPID: 22027
In child  => addr: 0x7fcef5100000 
In child  => reading *addr = P 
In child  => writing *addr ... 
In child  => ... writing *addr: done 
In child  => reading *addr = C 
In child  => exiting 
In parent => child process finished.
In parent  => reading *addr = C 
In parent => exiting.
© www.soinside.com 2019 - 2024. All rights reserved.