2016-01-10 56 views
3

我在客户端 - 服务器模型中使用共享内存。 当我的服务器通过使用sigkill而不是sigterm/sigint被用户杀死时,我无法做任何事情(按照预期),但是我的共享内存对象和信号仍然存在于/ dev/shm /中。如何在使用共享内存时处理杀死(kill -9)?

下一次我开始我的服务器时,我想创建一个完全相同名称的新对象,并且 - 以满足方式 - 失败并退出我的程序。

用户需要自行删除对象 - 这当然不是最好的选择。

我该如何处理?

我可以直接调用shm_open()而不用O_EXCL标志,最终破坏这个标志的用途。因为也许我的服务器已经有一个实例在运行并使用这个对象。

Pulseaudio似乎使用数字组合来保持其对象不同,并且不会因使用-9而将其杀死,所以似乎有一种方法。

+1

难道你没有其他方法来识别已经运行的服务器进程吗?一个pid文件,也许? – moooeeeep

+0

@moooeeeep这就是为什么我问如何处理它 - 似乎是一个好的开始,但我应该在哪里找到这样的文件? – Haini

回答

1

可能的服务器初始化大纲:

打开pid文件w/O_EXCL | O_WRONLY 如果成功写入PID 接近 打开SHM W/O_CREAT 做

打开pid文件瓦特/ O_RDONLY 读PID 使用kill(0),看看服务器活着 如果是的话,退出 如果没有,删除PID文件 关闭PID,开始在顶部再次

进程文件通常位于/ var/run中DIR和命名foobar.pid其中foobar的是程序名称

+0

所以结合这个http://unix.stackexchange.com/questions/12815/what-are-pid-and-lock-files-for我看到这是标题。似乎是正确的事情。谢谢!如果在几个小时内没有更容易的事情发生,我们会接受这个答案 – Haini

4

一种选择是使用IPC_RMID (见this)。

该选项标记了shm段的最后一个处理消失后进行清理。

对于信号灯,您可以查看robust mutexes。它确实要求你编写一个额外的错误情况(当持有互斥体的进程死亡时)。

您还可以选择使用文件锁,如果进程终止,则会释放这些文件锁(请参阅lockf())。

+0

当使用来自SHM_OVERVIEW(7)的函数时,是否有可能获得shmid,例如, POSIX共享内存的方式? 我看不到一种方法来获取它,因为System V共享内存操作和POSIX共享内存操作似乎有点不同。 仍然很棒的输入,要获得我拥有的所有选项并不容易。 – Haini

+0

不确定它是否适用于您的用例,但如果在所有进程按名称打开了'shm'后,如果可以调用'shm_unlink()',它在进程之后清理'shm'具有类似的效果消失。 – Ziffusion

+0

不幸的是,当我收到sigkill时,我无法调用shm_unlink()。在此之前调用它将是一场灾难,因为没有新的客户可以在调用它之后打开SHM。否则,这将是一个好方法。 – Haini