プログラムの実行中に、共有メモリ セグメントを開く必要があるすべてのプロセスがすでに開いていることがわかっている時点がある場合は、安全にリンクを解除できます。リンクを解除すると、オブジェクトはグローバル名前空間から削除されますが、ファイル記述子を開いたままにしておくプロセスが少なくとも 1 つある限り、そのまま残ります。それ以降にクラッシュが発生すると、ファイル記述子は自動的に閉じられ、参照カウントが減少します。リンクされていない共有メモリ ブロックへの開いている記述子がなくなると、削除されます。
これは、プロセスが共有メモリ ブロックを作成し、リンクを解除してフォークするというシナリオで役立ちます。子はファイル記述子を継承し、共有メモリ ブロックを使用して親と通信できます。両方のプロセスが終了すると、両方のファイル記述子が閉じられるため、ブロックは自動的に削除されます。
リンクが解除されている間、共有メモリ ブロックは他のプロセスで開くことができません。一方、 shm_open()
を使用すると リンクされていないブロックと同じ名前の場合、代わりにまったく異なる新しい共有メモリ ブロックが作成されます。
システム コマンドと Linux コマンド「fuser」を使用して、ファイルを開いたプロセスを一覧表示できる方法を見つけました。このようにして、共有メモリ ファイル (/dev/shm" にある) がまだ使用されているかどうかを確認し、使用されていない場合は削除できます。チェック / 削除 / 作成の操作は、プロセス間のクリティカル セクションで囲む必要があることに注意してください。名前付きミューテックス、名前付きセマフォ、またはファイル ロックを使用します。
std::string shm_file = "/dev/shm/" + service_name + "Shm";
std::string cmd_line = "if [ -f " + shm_file + " ] ; then if ! fuser -s " + shm_file + " ; then rm -f " + shm_file + " ; else exit 2 ; fi else exit 3 ; fi";
int res = system(cmd_line.c_str());
switch (WEXITSTATUS(res)) {
case 0: _logger.warning ("The shared memory file " + shm_file + " was found orphan and is deleted"); break;
case 1: _logger.critical("The shared memory file " + shm_file + " was found orphan and cannot be deleted"); break;
case 2: _logger.trace ("The shared memory file " + shm_file + " is linked to alive processes"); break;
case 3: _logger.trace ("The shared memory file " + shm_file + " is not found"); break;
}
いいえ - 少なくとも Linux では、カーネルにはこれを実行できるものは含まれていません。ある時点で shm_unlink() を呼び出して共有メモリ セグメントを取り除くのは、一部のアプリケーション次第です。