2017-08-08 7 views
4

再起動後にも、uint64_tタグの永続性が必要です。私は、メモリ・マップに、私は同じプロセスで作成したファイルboost::interprocess::mapped_regionを使用しています、これを達成するために永続性のためにメモリマップファイルを使用する - 揮発性が必要ですか?

bip::file_mapping file(filename.c_str(), bip::read_write); 
auto region = std::make_unique<bip::mapped_region>(file, bip::read_write); 

を私は、今、私ができる私のuint64_tタイプ

using Tag = uint64_t; 
Tag& curr_ = *reinterpret_cast<Tag*>(region->get_address()); 

にアドレスをキャストポストインクリメントタグを取得して「次のタグ」を取得し、その結果は再起動後も保持されます。

Tag next = curr_++; 

このファイルはに書かれたであり、から読み取られたであることに注意してください。純粋に永続性を提供することが目的です。

質問:

は、不揮発性であること、およびメモリマップされた地域、未定義の動作にI/Oを実行し、私のTag& curr_ますか?

私のコードにはvolatileというキーワードが必要ですか?以下

全作業例:

#include <boost/interprocess/mapped_region.hpp> 
#include <boost/interprocess/file_mapping.hpp> 
#include <sys/stat.h> 
#include <fstream> 
#include <cstdint> 
#include <memory> 
#include <iostream> 

namespace bip = boost::interprocess; 

using Tag = uint64_t; 

Tag& map_tag(const std::string& filename, 
      std::unique_ptr<bip::mapped_region>& region) 
{ 
    struct stat buffer; 
    if (stat(filename.c_str(), &buffer) != 0) 
    { 
     std::filebuf fbuf; 
     fbuf.open(filename.c_str(), std::ios_base::in | 
            std::ios_base::out | 
            std::ios_base::trunc | 
            std::ios_base::binary); 

     Tag tag = 1; 
     fbuf.sputn((char*)&tag, sizeof(Tag)); 
    } 

    bip::file_mapping file(filename.c_str(), bip::read_write); 

    // map the whole file with read-write permissions in this process 
    region = std::make_unique<bip::mapped_region>(file, bip::read_write); 

    return *reinterpret_cast<Tag*>(region->get_address()); 
} 

class TagBroker 
{ 
public: 
    TagBroker(const std::string& filename) 
     : curr_(map_tag(filename, region_)) 
    {} 

    Tag next() 
    { 
     return curr_++; 
    } 

private: 
    std::unique_ptr<bip::mapped_region> region_; 
    Tag& curr_; 
}; 

int main() 
{ 
    TagBroker broker("/tmp/tags.bin"); 

    Tag tag = broker.next(); 

    std::cout << tag << '\n'; 
    return 0; 
} 

出力:実行間

、永続性が保たれています。

$ ./a.out 
1 
$ ./a.out 
2 
$ ./a.out 
3 
$ ./a.out 
4 

、実際には、未定義の動作私のプロセスはTag& curr_への書き込み/からの読み取りのみであるため、またはそれだけで事故で働いているならば、とされ、これは、正しいかどうかはわかりません。

+0

私はあなたのプログラム以外のものがそのファイルに書き込んでいた場合にのみ揮発性が必要だと考えましたか? – AndyG

+0

@AndyGそれは私もですが、I/Oスケジューラはディスクからの実際の読み込み/書き込みを処理するので、これは別のプロセスと見なされますか?私の理解ではなく、volatile *は必須ではありませんが、私は100%確実ではないので、この質問 –

答えて

2

この場合、いいえ。

Boostのinterprocess/mapped_region.hppはmmapを使用しています。これはあなたにメモリマップされた領域へのポインタを返します。

別のプロセス(またはハードウェア)がファイルに書き込んでいる可能性がある場合は、volatileを使用する必要があります。

volatileが各アクセスのメモリからの読み出しを強制するので、それは、あなたが提供しなければならない最も基本的な同期だろう。あなたはプロセスを管理している場合は、セマフォなど、より高度な同期化を試みることがあります。)

+0

この特定のユースケースについては、私のプロセスは**ファイルへの書き込みは1つしかありません** 'volatile'は必須ではなく、セマフォなどの高度な同期もありません。 –

+0

そうです、ありがとうございます。 – AndyG

+0

ありがとうございます! –

関連する問題