在资源有限的不同进程之间建立共享内存?
Establishing shared memory between different processes with limited resources?
经过一些痛苦的调试,我意识到尝试使用 mmap 将 class 存储在共享内存中是非常愚蠢的。
所以,假设我有一个 class,其中包含 5 个变量(字符串和整数),我希望所有 运行ning 进程都可以访问这些变量。如果我不能使用像 boost 这样的非标准库,我该如何编写代码?
想到的一个想法非常糟糕,那就是让变量成为全局变量,然后简单地使用几次 mmap。起初,我尝试这样做,但使用最初在 class 中声明的变量,然后在构造函数中映射,但据我了解,这也不起作用。
我想补充一点,我被迫使用不支持 MAP_ANONYMOUS 且仅支持 MAP_ANON 的版本。
坚持phone。我,在今天早上的阴霾中,忘记了我之前测试过对象 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 风格的字符串吗?
你的问题是 C++ 类型太聪明了,不适合共享内存,包括 std::string
,更不用说 unique_ptr
或容器了。
在内部,一个字符串将包含另一个指针。地狱就在这里:即使你把你的字符串放在共享内存中,默认情况下,它也会指向一个进程的动态内存。
恕我直言,这是一个用例,用于记住所有优秀的旧 C 类型都可以从 C++ 使用。那个固定大小的字符数组并不总是那么糟糕,如果你能接受你的话的最大大小的约束。
我会使用:
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] = `[=10=]`;
for (int i=0; i<wLen; i++) wCopy[i] = '_';
wCopy[wLen] = `[=10=]`;
cout<<"wCopy in init is: " << word <<endl;
strikes = 0;
cout << wCopy <<endl;
solved = false;
test = 0;
}
}
这样,您就可以确保该结构使用的所有元素都驻留在共享内存中。一旦分配了它的成员函数 init
.
就初始化结构
经过一些痛苦的调试,我意识到尝试使用 mmap 将 class 存储在共享内存中是非常愚蠢的。
所以,假设我有一个 class,其中包含 5 个变量(字符串和整数),我希望所有 运行ning 进程都可以访问这些变量。如果我不能使用像 boost 这样的非标准库,我该如何编写代码?
想到的一个想法非常糟糕,那就是让变量成为全局变量,然后简单地使用几次 mmap。起初,我尝试这样做,但使用最初在 class 中声明的变量,然后在构造函数中映射,但据我了解,这也不起作用。
我想补充一点,我被迫使用不支持 MAP_ANONYMOUS 且仅支持 MAP_ANON 的版本。
坚持phone。我,在今天早上的阴霾中,忘记了我之前测试过对象 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 风格的字符串吗?
你的问题是 C++ 类型太聪明了,不适合共享内存,包括 std::string
,更不用说 unique_ptr
或容器了。
在内部,一个字符串将包含另一个指针。地狱就在这里:即使你把你的字符串放在共享内存中,默认情况下,它也会指向一个进程的动态内存。
恕我直言,这是一个用例,用于记住所有优秀的旧 C 类型都可以从 C++ 使用。那个固定大小的字符数组并不总是那么糟糕,如果你能接受你的话的最大大小的约束。
我会使用:
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] = `[=10=]`;
for (int i=0; i<wLen; i++) wCopy[i] = '_';
wCopy[wLen] = `[=10=]`;
cout<<"wCopy in init is: " << word <<endl;
strikes = 0;
cout << wCopy <<endl;
solved = false;
test = 0;
}
}
这样,您就可以确保该结构使用的所有元素都驻留在共享内存中。一旦分配了它的成员函数 init
.