【问题标题】:Sharing memory between three processes with semaphores使用信号量在三个进程之间共享内存
【发布时间】:2020-09-06 14:27:15
【问题描述】:

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

输出应该看起来像“读取:123”,但我得到“读取: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】:

    这是一个固定的答案,带有经过修改和简化的程序和解释。

    创建子进程时,父进程使用的大部分环境都是继承的:共享内存段会自动继承 - 您不需要运行任何 shmat、shmget 或 shmctl 例程。

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

    我在我的代码中简化了你的例子:

    • 只有 2 个进程:父进程和子进程
    • 进程中不使用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.
    

    【讨论】:

      猜你喜欢
      • 2012-01-11
      • 1970-01-01
      • 2015-11-19
      • 1970-01-01
      • 2013-08-20
      • 1970-01-01
      • 2011-11-06
      • 1970-01-01
      • 2012-06-22
      相关资源
      最近更新 更多