を共有するというアイデアが出ましたブーストライブラリのメモリ。
概念は、プログラムが初めて実行されるときに、特定のパラメータで呼び出された別のプロセスを作成することです(はい、これは一種のフォークですが、この方法ではポータブルソリューションがあります)。並列処理は共有メモリの初期化を処理し、終了信号を待つだけです。
次の実装の主な欠点は、(共有メモリを扱う)サーバーの初期化が完了する前に、理論的には、クライアント(ない管理者)の共有メモリを開くことができ、ということです。
ああ、デモンストレーションのためだけに、ベース0の実行インデックスを印刷しています。ここにコード。
#include <cstring>
#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <csignal>
#include <boost/process.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
static constexpr const char* daemonizer_string = "--daemon";
static constexpr const char* shared_memory_name = "shared_memory";
static std::mutex waiter_mutex;
static std::condition_variable waiter_cv;
struct shared_data_type
{
std::size_t count = 0;
};
extern "C"
void signal_handler(int)
{
waiter_cv.notify_one();
}
int main(int argc, const char* argv[])
{
namespace bp = boost::process;
namespace bi = boost::interprocess;
if(argc == 2 and std::strcmp(argv[1], daemonizer_string) == 0)
{
struct shm_remove
{
shm_remove() { bi::shared_memory_object::remove("shared_memory"); }
~shm_remove() { bi::shared_memory_object::remove("shared_memory"); }
} shm_remover;
bi::shared_memory_object shm(bi::create_only, shared_memory_name, bi::read_write);
shm.truncate(sizeof(shared_data_type));
bi::mapped_region region(shm, bi::read_write);
void* region_address = region.get_address();
shared_data_type* shared_data = new (region_address) shared_data_type;
std::signal(SIGTERM, signal_handler);
{
std::unique_lock<std::mutex> lock(waiter_mutex);
waiter_cv.wait(lock);
}
shared_data->~shared_data_type();
}
else
{
bi::shared_memory_object shm;
try
{
shm = bi::shared_memory_object(bi::open_only, shared_memory_name, bi::read_write);
}
catch(std::exception&)
{
using namespace std::literals::chrono_literals;
bp::spawn(argv[0], daemonizer_string);
std::this_thread::sleep_for(100ms);
shm = bi::shared_memory_object(bi::open_only, shared_memory_name, bi::read_write);
}
bi::mapped_region region(shm, bi::read_write);
shared_data_type& shared_data = *static_cast<shared_data_type*>(region.get_address());
std::cout << shared_data.count++ << '\n';
}
}
唯一の標準的なメカニズムは、ファイルを使用することです。他のソリューションはプラットフォームに依存します。 –
@FrançoisAndrieuxプラットフォームに依存するソリューションを知っていますか? –
プレーン・ファイルのみが動作しません(データベースは機能しますか?)あなたのターゲットプラットフォームは何ですか? Linux? Windows? – nefas