使用共享内存时如何处理被杀(kill -9)?
How to handle getting killed (kill -9) while using Shared Memory?
我在客户端-服务器模型中使用共享内存。
当我的服务器被用户使用 sigkill 而不是 sigterm / sigint 杀死时,我对此无能为力(如预期的那样),但我的共享内存对象和信号量仍然存在于 /dev/shm/.
下次我启动我的服务器时,我想创建一个名称完全相同的新对象,并且 - 正如预期的那样 - 这失败了,我退出了我的程序。
用户需要自己删除对象 - 这当然不是最好的选择。
我该如何处理?
我可以在没有 O_EXCL 标志的情况下调用 shm_open(),最终破坏了这个标志的目的。因为也许我的服务器 运行 已经有一个实例并使用了这个对象。
Pulseaudio 似乎使用数字组合来保持它的对象不同,并且不会因用 -9 杀死它而受到影响,所以似乎有办法。
可能的服务器初始化概要:
打开 pid 文件 w/O_EXCL | O_WRONLY
如果成功写pid
关
打开 shm w/O_CREAT
完成
打开pid文件w/O_RDONLY
读取 pid
使用 kill(0) 查看服务器是否存活
如果是,退出
如果不是,删除 pid 文件
关闭 pid,重新从顶部开始
Pid 文件通常位于 /var/run 目录并命名为 foobar.pid 其中 foobar 是程序名称
一种选择是使用 IPC_RMID
(参见 this)。
此选项标记 shm
段,以便在附加到它的最后一个进程消失后进行清理。
信号量可以看robust mutexes。它确实需要您为额外的错误情况编写代码(当持有互斥锁的进程死亡时)。
您还可以选择使用文件锁,如果进程终止,文件锁将被释放(请参阅 lockf())。
我在客户端-服务器模型中使用共享内存。 当我的服务器被用户使用 sigkill 而不是 sigterm / sigint 杀死时,我对此无能为力(如预期的那样),但我的共享内存对象和信号量仍然存在于 /dev/shm/.
下次我启动我的服务器时,我想创建一个名称完全相同的新对象,并且 - 正如预期的那样 - 这失败了,我退出了我的程序。
用户需要自己删除对象 - 这当然不是最好的选择。
我该如何处理?
我可以在没有 O_EXCL 标志的情况下调用 shm_open(),最终破坏了这个标志的目的。因为也许我的服务器 运行 已经有一个实例并使用了这个对象。
Pulseaudio 似乎使用数字组合来保持它的对象不同,并且不会因用 -9 杀死它而受到影响,所以似乎有办法。
可能的服务器初始化概要:
打开 pid 文件 w/O_EXCL | O_WRONLY 如果成功写pid 关 打开 shm w/O_CREAT 完成
打开pid文件w/O_RDONLY 读取 pid 使用 kill(0) 查看服务器是否存活 如果是,退出 如果不是,删除 pid 文件 关闭 pid,重新从顶部开始
Pid 文件通常位于 /var/run 目录并命名为 foobar.pid 其中 foobar 是程序名称
一种选择是使用 IPC_RMID
(参见 this)。
此选项标记 shm
段,以便在附加到它的最后一个进程消失后进行清理。
信号量可以看robust mutexes。它确实需要您为额外的错误情况编写代码(当持有互斥锁的进程死亡时)。
您还可以选择使用文件锁,如果进程终止,文件锁将被释放(请参阅 lockf())。