Boost进程间共享内存需要重映射,当其中一个进程截断共享内存以获得动态增长的大小时,也会重新获取地址。代码如下,在实际情况下,消费者mapping
可以了解生产者trunc
每次创建的新内存界限。但是,当trunc
创建更大的内存时,当输入更大的偏移量到mapping
时,映射会崩溃。
./trunc 10
./mapping
input 9, output is 9.
./trunc 10000,
input 9999 to mapping process, then segmentation fault.
trunc.cpp
#include <iostream>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
namespace bi = boost::interprocess;
int main(int argc, char* argv[]) {
bi::shared_memory_object shm(bi::open_or_create, "testshm", bi::read_write);
shm.truncate(sizeof(int) * std::atoi(argv[1]));
bi::mapped_region reg(shm, bi::read_write, 0);
int* p = (int*)reg.get_address();
for(std::size_t i = 0; i < std::atoi(argv[1]); ++i)
p[i] = i;
return 0;
}
mapping.cpp
#include <iostream>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
namespace bi = boost::interprocess;
int main(int argc, char* argv[]) {
bi::shared_memory_object shm(bi::open_only, "testshm", bi::read_only);
bi::mapped_region reg(shm, bi::read_only, 0);
int* p = (int*)reg.get_address();
do {
std::cout << "Please input offset:" << std::endl;
int offset;
std::cin >> offset;
std::cout << "Integer @" << offset << " is " << p[offset] << std::endl;
} while(true);
return 0;
}
答案 0 :(得分:1)
在我的系统上不会发生这种情况。
可悲的是,我无法向你展示Coliru(因为不支持共享内存),但您可以使用以下代码重新测试:
#include <iostream>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
namespace bi = boost::interprocess;
static char const* const SHM_NAME = "sotest-5b4f4154-0c7a-48f4-9be6-33b99094cea4";
int main(int argc, char** argv) {
if (argc>1) {
bi::shared_memory_object shm(bi::open_or_create, SHM_NAME, bi::read_write);
shm.truncate(sizeof(int) * std::atoi(argv[1]));
bi::mapped_region reg(shm, bi::read_write);
int* p = reinterpret_cast<int*>(reg.get_address());
for(int i = 0; i < std::atoi(argv[1]); ++i)
p[i] = i;
std::cout << "Truncated and filled to " << reg.get_size() << "\n";
} else {
bi::shared_memory_object shm(bi::open_only, SHM_NAME, bi::read_only);
bi::mapped_region reg(shm, bi::read_only, 0);
size_t N = reg.get_size() / 4;
int const* p = reinterpret_cast<int const*>(reg.get_address());
size_t index;
while (std::cout << "Please input index: " && std::cin >> index) {
if (index < N)
std::cout << "Integer @" << index << " is " << p[index] << "\n";
else
std::cout << "Index " << index << " out of bounds [0.." << N << ")\n";
}
std::cout << "Bye\n";
}
}
它主要改变了一些小事:
reinterpret_cast
trunc
和mapping
合并为一个文件我用以下方法测试:
./sotest 10
xxd /dev/shm/sotest-5b4f4154-0c7a-48f4-9be6-33b99094cea4 | tail -5
ls -ltra /dev/shm/sotest-5b4f4154-0c7a-48f4-9be6-33b99094cea4
./sotest <<< "0 1 2 3 999 9999 10000"
输出:
Truncated and filled to 40
00000000: 0000 0000 0100 0000 0200 0000 0300 0000 ................
00000010: 0400 0000 0500 0000 0600 0000 0700 0000 ................
00000020: 0800 0000 0900 0000 ........
-rw-r--r-- 1 sehe sehe 40 jan 7 21:08 /dev/shm/sotest-5b4f4154-0c7a-48f4-9be6-33b99094cea4
Please input index: Integer @0 is 0
Please input index: Integer @1 is 1
Please input index: Integer @2 is 2
Please input index: Integer @3 is 3
Please input index: Index 999 out of bounds [0..10)
Please input index: Index 9999 out of bounds [0..10)
Please input index: Index 10000 out of bounds [0..10)
Please input index: Bye
sotest 10000
xxd /dev/shm/sotest-5b4f4154-0c7a-48f4-9be6-33b99094cea4 | tail -5
ls -ltra /dev/shm/sotest-5b4f4154-0c7a-48f4-9be6-33b99094cea4
./sotest <<< "0 1 2 3 999 9999 10000"
输出:
Truncated and filled to 40000
00009bf0: fc26 0000 fd26 0000 fe26 0000 ff26 0000 .&...&...&...&..
00009c00: 0027 0000 0127 0000 0227 0000 0327 0000 .'...'...'...'..
00009c10: 0427 0000 0527 0000 0627 0000 0727 0000 .'...'...'...'..
00009c20: 0827 0000 0927 0000 0a27 0000 0b27 0000 .'...'...'...'..
00009c30: 0c27 0000 0d27 0000 0e27 0000 0f27 0000 .'...'...'...'..
-rw-r--r-- 1 sehe sehe 40000 jan 7 21:08 /dev/shm/sotest-5b4f4154-0c7a-48f4-9be6-33b99094cea4
Please input index: Integer @0 is 0
Please input index: Integer @1 is 1
Please input index: Integer @2 is 2
Please input index: Integer @3 is 3
Please input index: Integer @999 is 999
Please input index: Integer @9999 is 9999
Please input index: Index 10000 out of bounds [0..10000)
Please input index: Bye
sotest 10001
xxd /dev/shm/sotest-5b4f4154-0c7a-48f4-9be6-33b99094cea4 | tail -5
ls -ltra /dev/shm/sotest-5b4f4154-0c7a-48f4-9be6-33b99094cea4
./sotest <<< "0 1 2 3 999 9999 10000"
输出:
Truncated and filled to 40004
00009c00: 0027 0000 0127 0000 0227 0000 0327 0000 .'...'...'...'..
00009c10: 0427 0000 0527 0000 0627 0000 0727 0000 .'...'...'...'..
00009c20: 0827 0000 0927 0000 0a27 0000 0b27 0000 .'...'...'...'..
00009c30: 0c27 0000 0d27 0000 0e27 0000 0f27 0000 .'...'...'...'..
00009c40: 1027 0000 .'..
-rw-r--r-- 1 sehe sehe 40004 jan 7 21:08 /dev/shm/sotest-5b4f4154-0c7a-48f4-9be6-33b99094cea4
Please input index: Integer @0 is 0
Please input index: Integer @1 is 1
Please input index: Integer @2 is 2
Please input index: Integer @3 is 3
Please input index: Integer @999 is 999
Please input index: Integer @9999 is 9999
Please input index: Integer @10000 is 10000
Please input index: Bye
如果这会对您的系统产生不同的结果,请告诉我们。另外,报告 平台详细信息/版本使用该案例。