首页 > 解决方案 > 如何将标准输出发送到共享 mmap?

问题描述

这是一个家庭作业。任务是复制 shell 命令:ls | wc -l在 C 中使用共享内存,mmap()同时遵循 POSIX 标准。

这是我解决问题的原始方法:

  1. 创建共享内存区域sh_mem
  2. 分叉进程
  3. 子进程内部:
    • 绑定stdoutsh_mem某种方式写入
    • 称呼execlp("ls", "ls", NULL)
  4. 在父进程内部:
    • wait(NULL)为了孩子完成
    • 绑定以某种方式stdin读取sh_mem
    • 称呼execlp("wc", "wc", "-l", NULL)

问题:

但是,我想不出如何将stdin/绑定stdoutsh_mem. 我用管道做到了,并认为我可以在这里实现类似的东西,但我找不到任何方法。

你能给我一些关于如何解决这个问题的建议吗?

代码:(不完整)

这是我到目前为止编写的代码,但现在它非常没用。它只是从孩子和父母那里读写。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h> 
#include <errno.h> 
#include <sys/wait.h>
#include <sys/mman.h>
#include <string.h>

int main() {
    const char* p_msg = "Hello";
    const char* c_msg = "World";

    void* shmem = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);

    memcpy(shmem, p_msg, sizeof(p_msg));

    int pid = fork();

    if(pid == 0){
        printf("Child reads: %s\n", shmem);
        memcpy(shmem, c_msg, sizeof(c_msg));
    }
    else {
        printf("Parent reads: %s\n", shmem);
        sleep(1);
        printf("after one sec: %s\n", shmem);
    }
}

可能的解决方案1:

我想到了另一种方法,我使用文件来写入文件并有一个内存映射到文件。但是,如果文件被用于进行实际的读写,我看不到共享内存的实用性。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h> 
#include <errno.h> 
#include <sys/wait.h>
#include <sys/mman.h>
#include <string.h>

int main() {
    int returnstatus;

    // Create a file
    int fd = open("shmem.txt", O_RDWR | O_CREAT, O_RDWR);

    // Create a memory map of the file
    void* sh_mem = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);


    // Create a child process   int pid = fork();

    if(pid == 0){
        // Inside Child process
        // Link stdout to file

        dup2(fd, 1);    

        // Close unused fd
        close(fd)       

        // Execute ls
        execlp("ls", "ls", NULL);

    else {
        // Inside Parent Process

        // Link stdin to file/sh_mem

        // Execute wc
    }

}


可能的解决方案2:

由@kaylum 建议。用于shm_open()获取fd共享内存。

我试过了,但它并没有像我预期的那样工作。它不绑定 thestdout或 thestdin


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h> 
#include <errno.h> 
#include <sys/wait.h>
#include <sys/mman.h>
#include <string.h>

int main() {
    int returnstatus;

    // Get the fd of the map
    int fd = open("sh.file", O_RDWR, O_RDWR);

    // Create a memory map of the file
    void* sh_mem = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

    // Create a child process
    int pid = fork();

    if(pid == 0){
        // Inside Child process
        // Link stdout to file
        dup2(fd, 1);    

        // Close unused fd
        close(fd);      

        // Execute ls
        execlp("ls", "ls", NULL);
    }   
    else { // Inside Parent Process
        // Link stdin to file
        dup2(fd, 0);

        // CLose unused fd
        close(fd);

        // Execute wc
        execlp("wc", "wc", "-l", NULL);
    }

}


标签: clinuxposixshared-memorymmap

解决方案


推荐阅读