在资源有限的不同流程之间建立共享内存?

时间:2015-04-29 12:34:32

标签: c++ c process shared-memory

经过一些痛苦的调试,我意识到尝试使用mmap在共享内存中存储一​​个类是非常愚蠢的。

所以,假设我有一个类似5个变量(字符串和整数)的类,我希望所有正在运行的进程都可以访问它。如果我不能使用像boost这样的非标准库,我怎么能去编码?

我想到的一个想法是,将变量设为全局变量,然后简单地使用mmap几次。起初,我尝试这样做,但最初在类中声明的变量然后在构造函数中mmap'd,但从我的理解,这也不起作用。

我想补充一点,我不得不使用不支持MAP_ANONYMOUS且只支持MAP_ANON的版本。

握住手机。我,在今天早上的阴霾,忘记了我之前测试过对象mmap'ing并设法以共享方式从两个不同的进程更新对象的成员。我现在相信我的问题完全在于构造初始化以及我声明对象的方式。然而,我当前代码中的一个非常相似的访问导致进程突然结束...

这是我的代码:

Hangman * H; // I've tried this with and without using new here
             // and this talk of placement new may show illumination
H =(Hangman*) mmap(NULL, sizeof *H, PROT_READ | PROT_WRITE,
                    MAP_SHARED | MAP_ANON, -1, 0);

这是对象:

struct Hangman{

        string word;
        string wCopy;
        int strikes, wLen;
        bool solved;
        int test;

        Hangman(){
                word = getWord();
                wLen  = word.length();
                wCopy = word;
                cout<<"wCopy in construc is: " <<wCopy<<endl;
                for(int i = 0; i < wLen; i++)
                        wCopy[i] = '_';
                strikes = 0;
                cout << wCopy <<endl;
                solved = false;
                test = 0;
        }  
 //(...)
 };

...现在我记得int访问很好并且字符串访问运行amok导致我相信我不应该在这里使用字符串。如果是这种情况,我应该使用c样式字符串吗?

1 个答案:

答案 0 :(得分:0)

您的问题是C ++类型太聪明,无法容纳共享内存,包括std::string,而不是unique_ptr或容器。

在内部,字符串将包含另一个指针。地狱就在这里:即使你把你的字符串放在共享内存中,默认情况下,它也会指向一个进程的动态内存。

恕我直言,这是一个用例,用于记住可以在C ++中使用所有好的旧C类型。那个固定大小的char数组并不总是那么糟糕,如果你能接受你单词最大大小的约束。

我会用:

struct Hangman{

    char word[MAXSIZE];
    char wCopy[MAXSIZE];
    int strikes, wLen;
    bool solved;
    int test;

    void init(string orig_word) {

        wLen = orig_word.length();
        if (wLen >= MAXSIZE) {
            // ERROR word is too long
        }
        strncpy(word, orig, wLen);
        word[wLen] = `\0`;
        for (int i=0; i<wLen; i++) wCopy[i] = '_';
        wCopy[wLen] = `\0`;

        cout<<"wCopy in init is: " << word <<endl;
        strikes = 0;
        cout << wCopy <<endl;
        solved = false;
        test = 0;
    }
}

这样,您可以确保结构使用的所有元素都驻留在共享内存中。并使用其成员函数init初始化结构。