【问题标题】:C++ - Forked Process Can't Read from Shared MemoryC++ - 分叉进程无法从共享内存中读取
【发布时间】:2018-03-11 11:17:09
【问题描述】:

我正在学习进程管理和共享内存,我想知道是否有人可以帮助我。我正在尝试使用分叉的父进程读取一个大型文本文件(2MB)并将其提供给相应的子进程以进行......很好......处理。但是,我的概念证明小程序无法读取我写入共享内存的数据。调用“容量()”和“长度()”工作正常,但实际上尝试检索存储在那里的数据会返回一个空字符串。我什至尝试将指针中的内容复制到字符数组中,但仍然没有。有什么想法吗?

程序代码:

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

using namespace std;

#define SHM_SIZE 2000000    // 2 MB of shared memory

int main(int argc, char* argv[])
{
    string* data = (string*) mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, 
    MAP_SHARED | MAP_ANONYMOUS, -1, 0);

printf("Shared memory capacity before reserve: %ld\n", data->capacity());
data->reserve(SHM_SIZE); // make sure string can use all available space
printf("Shared memory capacity after reserve: %ld\n", data->capacity());

switch(fork())
{
    case -1:
        printf("Something went wrong ... exiting program\n");
        break;
    case 0:
        usleep(1000 * 1000 * 2); // force child to wait for sanity purposes
        printf("\nChild capacity:  %ld\n", data->capacity());
        printf("Child contents:  %s\n", data->c_str());
        break;
    default:
        // Sample input ... file reading logic omitted for brevity
        *data = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean leo elit, aliquam "
            "vitae aliquam sed, rhoncus et mi. Aliquam erat volutpat. Phasellus non urna sit amet "
            "enim tincidunt aliquam quis sit amet orci. Maecenas velit turpis, venenatis eu diam "
            "vel, varius volutpat nulla. Nam mi massa, tristique eget imperdiet id, dictum ut urna. "
            "Nulla id massa placerat, finibus purus quis, ornare neque. Vivamus eget varius ante. "
            "Aenean varius ac neque quis ultricies. Donec vitae bibendum dolor, vitae tempor augue.";
        printf("\nParent capacity:  %ld\n", data->capacity());
        printf("Parent contents:  %s\n", data->c_str());

        wait(NULL);
        munmap(data, sizeof *data);
        printf("\nHello world\n");
        break;
}

return 0;
}

输出:

MacBook-Pro:sharedmem-test slehr$ ./sharedmem-mapred 
Shared memory capacity before reserve: 22
Shared memory capacity after reserve: 2000015

Parent capacity:  2000015
Parent contents:  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean leo elit, aliquam vitae aliquam sed, rhoncus et mi. Aliquam erat volutpat. Phasellus non urna sit amet enim tincidunt aliquam quis sit amet orci. Maecenas velit turpis, venenatis eu diam vel, varius volutpat nulla. Nam mi massa, tristique eget imperdiet id, dictum ut urna. Nulla id massa placerat, finibus purus quis, ornare neque. Vivamus eget varius ante. Aenean varius ac neque quis ultricies. Donec vitae bibendum dolor, vitae tempor augue.

Child capacity:  2000015
Child contents:  

Hello world
MacBook-Pro:sharedmem-test slehr$ 

【问题讨论】:

  • 不,认真的吗? string* data = (string*) mmap(...)?这不可能。尝试像memcpy 这样的映射地址。请注意,string 不仅仅是指针之类的东西,它还是一个对象(其中包含一个指针)。
  • C 和 C++ 是不同的语言。特别是在这里你似乎有一个 C++ 问题,如何让 C++ string 指向共享内存。我删除了 C 标签。

标签: c++ fork shared-memory process-management


【解决方案1】:

std::string 可能是一些具有大小、长度、指针(或类似的东西)的数据结构。你不能指望它的内部指针指向共享内存

对于mmap-ed 内存,您应该使用原始指针,例如

auto data = (char*) mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, 
                         MAP_SHARED | MAP_ANONYMOUS, -1, 0);

当然你应该测试失败:

if (data==(char*)MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); };

再读一遍mmap(2)

您可以考虑shm_overview(7)(并查看sem_oveview(7) 进行同步)

阅读Advanced Linux Programming

【讨论】:

  • 您对 std::string 数据结构是绝对正确的......我将其更改为 char* 并且能够在 memcpy() 的帮助下使其工作。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-29
  • 1970-01-01
相关资源
最近更新 更多