4

ミューテックスで保護しているコレクションがあります。初期化後は読み取られるだけなので、ミューテックスは必要ありません。

コレクションは、グローバルな静的初期化子で初期化および設定されます。グローバルな静的初期化が単一の翻訳単位内で保証されていることを知っています。グローバルな静的初期化がシングル スレッドになるという保証はありますか?


Schwarz カウンターによって保護され、他の静的オブジェクトのコンストラクターによって設定される静的コレクションがあります。コンテナはミューテックスに関連付けられています。開始後にコレクションが読み取り専用であることを考えると、main静的コンストラクターが単一のスレッドで呼び出されることを保証できる場合は、ミューテックスを取り除きたいと思います。

私の理解では、静的な初期化順序は一般に単一の翻訳単位内で明確に定義されていますが、翻訳単位間では指定されていません。標準では、ランタイムが提供するさまざまなスレッドによって静的オブジェクトを初期化/構築することが許可されていますか?


シュヴァルツカウンター:

ヘッダー ファイル:

struct Init
{
   Init();
   ~Init();
};
namespace
{
   Init _init;
}
extern std::map<int, std::unique_ptr<...>> &protected;

ソースファイル:

namespace
{
   int init_count;
   std::aligned_storage<sizeof(std::map<int, std::unique_ptr<...>>), alignof(std::map<int, std::unique_ptr<...>>>)> protected_storage;
}
std::map<int, std::uniqe_ptr<...>> &protected = *reinterpret_cast<std::map<int, std::unique_ptr<...>> *>(&protected_storage);
Init::Init()
{
   if (!init_counter++)
   {
      new(&protected_storage) std::map<int, std::unique_ptr<...>>();
   }
}
Init::~Init()
{
   if (!--init_counter)
   {
      protected.~std::map<int, std::unique_ptr<...>>();
   }
}

コレクション人口:

struct helper
{
   helper(...)
   {
      protected.insert(std::make_pair(...));
   }
};

ヘルパーの静的インスタンスを作成するマクロが展開されます。

4

1 に答える 1