shm_open()
私の質問は、 と を使用して取得したメモリの初期化に関するものmmap()
です。私がいくつかの場所で見た一般的なアドバイスの 1 つはshm_open()
、フラグを付けて呼び出すO_CREAT|O_EXCL
ことです。それが成功した場合、私たちは共有メモリの最初のユーザーであり、それを初期化できます。そうでない場合、私たちは最初ではなく、共有メモリは別のプロセスによって既に初期化されています。 .
しかし、私が理解していることshm_open
と、Linux で行ったテストから、これは機能しません。共有メモリ オブジェクトの最後のユーザーがマップ解除されて閉じられた後でも、共有メモリ オブジェクトがシステムに残ります。shm_open
で呼び出し、記述子を閉じて終了する単純なテスト プログラムはO_CREAT|O_EXCL
、最初の実行では成功しますが、2 回目の実行では、その時点で他の誰も共有メモリを使用していなくても失敗します。
実際、(少なくとも私がテストしたシステムでは) の動作はshm_open
とほとんど同じであるように思われますopen()
: 単純なテスト プログラムを変更して共有メモリに何かを書き込んで (によって取得されたポインタを介してmmap
) 終了すると、共有メモリ オブジェクトはその内容を永続的に保持します (別の簡単なプログラムを実行して、以前に書き込んだデータを読み戻すことができます)。
では、使用に関するアドバイスは間違っているのでしょうかshm_open
、O_CREAT|O_EXCL
それとも何か不足していますか?
で共有メモリオブジェクトを削除できることは知っていますがshm_unlink()
、それはより多くの問題を引き起こすだけのようです:
プロセスが呼び出す前に終了すると
shm_unlink()
、上記の問題に戻ります。他のいくつかのプロセスがまだ同じ共有メモリにマップされている間にあるプロセスが呼び出した場合
shm_unlink()
、これらの他のプロセスは通常どおりそれを使用し続けます。shm_open()
ここで、別のプロセスが来て同じ名前で指定された呼び出しを行うとO_CREAT
、実際には同じ名前の新しい共有メモリ オブジェクトの作成に成功します。これは、他のプロセスがまだ使用している古い共有メモリ オブジェクトとはまったく関係ありません。これで、共有メモリを介して他のプロセスと通信しようとしているプロセスがあり、間違ったチャネルを使用していることにまったく気づいていません。
私は、少なくとも 1 つのハンドルが開かれている限り共有メモリ オブジェクトが存在する Windows のセマンティクスに慣れているため、この Posix は非常に混乱します。