【问题标题】:c++ Synchronize shared memory when readingc++读取时同步共享内存
【发布时间】:2018-09-23 07:42:49
【问题描述】:

我想同步一个shared_memory_object 来读取iff shared_memory_object 已经存在。这是我用于与 bool 变量同步的代码。

boost::interprocess::shared_memory_object my_shared_mat;
bool mat_ready = true;
while (mat_ready)
{
    try {
        my_shared_mat = boost::interprocess::shared_memory_object(
            boost::interprocess::open_only,  // only open
            "shared_mat",                    // name
            boost::interprocess::read_only); // read-only mode
        mat_ready = false;
    }
    catch (boost::interprocess::interprocess_exception &ex) {
        std::cout << ex.what() << std::endl;
        mat_ready = true;
    }
}

boost::interprocess::mapped_region region(my_shared_mat, boost::interprocess::read_only);

如果共享内存存在,我没有任何问题,数据在进程之间共享,但如果共享内存不存在,程序在 mapped_region 调用时崩溃。

【问题讨论】:

  • 除非对象存在,否则您显示的代码不可能到达mapped_region 调用。我建议你展示你的真实代码。
  • 我正在另一个进程中创建对象。如果尚未创建进程,我想知道如何创建共享内存以读取此文件。如果未创建共享内存,它将引发异常,因此我将 while(mat_ready) 用于说明这一点。但是,如果我这样做,它会在调用 mapped_region 时崩溃。
  • @JonathanPotter 如果服务器仍在创建映射区域(调整大小等),则存在竞争条件。是的,代码没有显示它,但它也没有显示同步。

标签: c++ boost shared-memory


【解决方案1】:

如果您想与另一个进程同步,请使用同步原语:condition variablemutex

#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
#include <iostream>

namespace bip   = boost::interprocess;
using Mutex     = bip::named_mutex;
using Condition = bip::named_condition;

int main(int argc, char**) {
    Mutex     mx(bip::open_or_create, "shared_mat_mx");
    Condition cv(bip::open_or_create, "shared_mat_cv");

    if (argc>1) { // server
        auto mat = bip::shared_memory_object(bip::create_only, "shared_mat", bip::read_write);
        mat.truncate(10 << 10); // 10kb

        bip::mapped_region region(mat, bip::read_only);

        {
            bip::scoped_lock<Mutex> lk(mx);
            cv.notify_all(); // notify all clients we're there
        }
    } else {
        {
            bip::scoped_lock<Mutex> lk(mx);
            cv.wait(lk); // wait for server signal
        }
        auto mat = bip::shared_memory_object(bip::open_only, "shared_mat", bip::read_only);
        bip::mapped_region region(mat, bip::read_only);

        std::cout << "Mapped the region of size " << region.get_size() << "\n";
    }
}

在后台运行多个客户端:

for a in {1..10}; do ./sotest& done

让他们都等着。启动服务器:

./sotest server

使他们都取得进步,并且他们表现出来:

Mapped the region of size 10240

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-31
    • 2014-10-26
    • 1970-01-01
    • 1970-01-01
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    相关资源
    最近更新 更多