共有メモリを使用していくつかのプロセスを実行しているときに、1 つを除いてすべてのプロセスを切り離します。
shmctl()
(そのプロセスで)共有メモリを削除する前に、最後のプロセスを切り離すことは理にかなっていますか?- それが意味をなさない場合、共有メモリを切り離した後に削除することは可能ですか?
の手動エントリにshmctl()
は、「最大で 1 つのプロセスがそれを使用している」または「プロセスが接続されていない」ことについては何も書かれていません。ただし、システムは、共有メモリ セグメントに接続されている既に実行中のプロセスを完全に中断することはできません。
shmid
によって返される (共有メモリ セグメント ID)だけが必要shmget()
です。共有メモリをアタッチする必要はありません(したがって、すでに run を実行している可能性がありますshmdt()
)。
Mac (macOS Sierra 10.12.3、GCC 6.3.0) で前の質問 ( C で共有データ構造を作成-t time
する) から派生したコードを使用してテストしたところ、プロセスを指定可能な期間スリープさせるオプションを追加しました。次に、共有メモリ セグメントを作成し、プロセスを開いたままにしました。ipcs -m
セグメントが存在することを以前は見ていました。次に、セグメントを削除しました。それは成功しました。で再確認するとipcs -m
、セグメントが共有から に変更されていましたIPC_PRIVATE
。スリープ プロセスが完了すると、共有メモリ セグメントは自動的に削除されます (プライベート セグメントは常に削除されます)。
$ shm-master -f shm-master -s 1024 -x -t 120 &
[1] 14392
$ ID: 0, File: shm-master
Key: 0x00041BF7
ShmID: 1441795
Shared memory allocated at 0x10F2B4000
Sleeping for 120 seconds
$ ipcs -m
IPC status from <running system> as of Wed Feb 15 11:56:37 PST 2017
T ID KEY MODE OWNER GROUP
Shared Memory:
m 65536 0x00fedc64 --rw-rw-rw- root wheel
m 65537 0x0052e2c1 --rw------- postgres daemon
m 65538 0x52042973 --rw------- root wheel
m 1441795 0x00041bf7 --rw------- jleffler staff
$ shm-master -f shm-master -s 1024 -d
ID: 0, File: shm-master
Key: 0x00041BF7
ShmID: 1441795
Shared memory removed
$ ipcs -m
IPC status from <running system> as of Wed Feb 15 11:56:47 PST 2017
T ID KEY MODE OWNER GROUP
Shared Memory:
m 65536 0x00fedc64 --rw-rw-rw- root wheel
m 65537 0x0052e2c1 --rw------- postgres daemon
m 65538 0x52042973 --rw------- root wheel
m 1441795 0x00000000 --rw------- jleffler staff
$ sleep 120; ipcs -m
Detached from shared memory
[1]+ Done shm-master -f shm-master -s 1024 -x -t 120
IPC status from <running system> as of Wed Feb 15 11:58:57 PST 2017
T ID KEY MODE OWNER GROUP
Shared Memory:
m 65536 0x00fedc64 --rw-rw-rw- root wheel
m 65537 0x0052e2c1 --rw------- postgres daemon
m 65538 0x52042973 --rw------- root wheel
$
これが他のシステムで起こるかどうかはわかりませんが、もっともらしい動作のように見えます。似たようなことが起こりそうです。
ちなみに、1 つのプロセスを実行してセグメントを作成し、2 つ目のプロセスを実行してセグメントにアタッチするだけで、どちらもスリープ モードで実行しても、観察された結果は実際には変わりませんでした。共有メモリ セグメント キーが 0 に変更され、プロセスは影響を受けず、セグメントは両方が完了した後に削除されました。