当一个进程截断由 boost 进程间库创建的共享内存时,进程需要重新映射
processes needs remap when one process truncate the shared memory created by boost interprocess library
当其中一个进程截断共享内存以动态增加大小时,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;
}
在我的系统上不会发生这种情况。
遗憾的是,我无法在 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";
}
}
它主要改变了一些小的东西:
- 名字
- 正在检查大小作为 truncated/before 索引
- 拼写
reinterpret_cast
- 常量正确性
- 将
trunc
和 mapping
合并到一个文件中
我测试它:
测试用例 1:截断 10
./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
测试用例 1:trunc 10000
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
测试用例 1:trunc 10001
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
如果这在您的系统上给出了不同的结果,请告诉我。还有,举报
平台 details/versions 使用了那个案例。
当其中一个进程截断共享内存以动态增加大小时,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;
}
在我的系统上不会发生这种情况。
遗憾的是,我无法在 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";
}
}
它主要改变了一些小的东西:
- 名字
- 正在检查大小作为 truncated/before 索引
- 拼写
reinterpret_cast
- 常量正确性
- 将
trunc
和mapping
合并到一个文件中
我测试它:
测试用例 1:截断 10
./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
测试用例 1:trunc 10000
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
测试用例 1:trunc 10001
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
如果这在您的系统上给出了不同的结果,请告诉我。还有,举报 平台 details/versions 使用了那个案例。