如何仅当shared_memory_object存在时同步其读取操作?
仅当共享内存存在时进行读取同步的优化实现
嘿,我来帮你搞定这个共享内存同步的问题。你想实现的是仅当shared_memory_object已存在时才执行读取同步,用bool变量循环尝试打开的思路是对的,但原代码的异常处理不完整,还有可以优化的地方,我给你梳理下改进方案:
原代码的问题点
你的代码里异常捕获部分被截断了,Boost共享内存操作抛出的是boost::interprocess::interprocess_exception类型的异常,必须明确捕获;另外,循环里每次创建临时对象赋值,加上没有延迟的忙等,会消耗大量CPU资源。
优化后的实现方案
这里有两种可靠的实现方式,你可以根据场景选择:
方式一:异常捕获+延迟重试
这种方式直接依赖异常处理来判断共享内存是否存在,同时增加延迟避免忙等:
#include <boost/interprocess/shared_memory_object.hpp> #include <boost/interprocess/mapped_region.hpp> #include <thread> #include <chrono> using namespace boost::interprocess; int main() { shared_memory_object my_shared_mat; bool mat_ready = true; while (mat_ready) { try { // 尝试打开已存在的只读共享内存 my_shared_mat = shared_memory_object( open_only, "shared_mat", read_only ); mat_ready = false; // 成功打开,退出循环 } catch (const interprocess_exception& ex) { // 共享内存尚未存在,等待100ms后重试 std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } // 成功打开后,映射内存区域进行读取 mapped_region region(my_shared_mat, read_only); const void* shared_data = region.get_address(); // 在这里处理共享内存中的数据... return 0; }
方式二:先检查存在性再尝试打开
这种方式先调用exists()检查共享内存是否存在,减少异常抛出的次数(异常处理开销相对较高),但要注意检查和打开不是原子操作,所以仍需捕获异常:
#include <boost/interprocess/shared_memory_object.hpp> #include <boost/interprocess/mapped_region.hpp> #include <thread> #include <chrono> using namespace boost::interprocess; int main() { shared_memory_object my_shared_mat; bool mat_ready = true; while (mat_ready) { if (shared_memory_object::exists("shared_mat")) { try { my_shared_mat = shared_memory_object(open_only, "shared_mat", read_only); mat_ready = false; } catch (const interprocess_exception& ex) { // 检查后共享内存被其他进程删除,重试 std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } else { // 共享内存不存在,等待后重试 std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } // 映射并处理数据... mapped_region region(my_shared_mat, read_only); const void* shared_data = region.get_address(); return 0; }
关键注意事项
- 异常类型:必须捕获
interprocess_exception,不要用泛型的std::exception,避免漏掉Boost共享内存的特定异常。 - 延迟调整:
sleep_for的时间可以根据你的业务场景调整,比如高实时性场景用更短的延迟,非实时场景用更长的延迟减少CPU占用。 - 原子性问题:方式二中的
exists()和open_only不是原子操作,所以即使检查存在,打开时仍可能失败(比如共享内存被其他进程删除),必须保留异常捕获。
内容的提问来源于stack exchange,提问作者Luis
相关产品推荐
相关产品推荐

