【问题标题】:Allow start only one copy of program in linux在linux中只允许启动一个程序副本
【发布时间】:2010-11-22 21:38:58
【问题描述】:

我只想要系统中我的程序的一份副本。如何从 C 代码中查找系统中的另一个副本?我想要这样的东西

# program &
[1] 12586
# program &
Program is already running

我的最佳想法是制作 .lock 文件。但我没有找到任何关于他们的准则。

谢谢。

【问题讨论】:

  • 听起来你想把你的程序作为一个守护进程运行
  • 它不是守护进程,而是类似的东西。问题是同时复制两个副本会导致数据崩溃。
  • 锁文件解决方案很好 - 套接字解决方案的意图相似。给您一个大问题:为什么如果有两个副本正在运行,您的程序会崩溃?如果我想在我的数据上运行一份副本,而 Fred 想在他的数据上运行一份副本呢?没有标准的内置机制,因为它并不像人们想的那样经常需要。
  • 补充 Jonathan Leffler 的评论,关键资源是数据,而不是程序。在数据上使用锁定文件,而不是在程序上。

标签: c linux unix


【解决方案1】:

我编写的一个守护进程打开了一个 UNIX 域套接字,用于常规的客户端-守护进程通信。然后其他实例检查它们是否可以连接到该套接字。如果可以的话,另一个实例正在运行。 编辑: 正如@psmears 所指出的,存在竞争条件。其他实例应该只是尝试创建相同的侦听套接字。如果它已在使用中,则会失败。

锁定文件比这种特殊情况更频繁地工作。您可以在众所周知的位置创建一个(空)文件,然后使用文件锁,例如fcntl(2)F_SETLKF_GETLK 来设置该文件的锁或确定是否持有锁。可能无法在 NFS 上工作。当您的进程终止时,锁会被清除,因此这应该可以工作,并且是可移植的(至少对于 HP-UX)。如果某些守护进程确定当前没有其他实例正在运行,它们喜欢将其 pid 转储到该文件中。

【讨论】:

  • UNIX 域套接字的想法是一个不错的想法——但与其尝试连接到套接字,不如尝试创建另一个具有相同名称的套接字。如果由于地址正在使用而失败,则守护程序已经在运行。 (这样做的原因是为了避免竞争条件 - 否则您的两个进程可能几乎同时启动 - 两者都将尝试连接到尚不存在的套接字;两者都会成功,然后两者都将继续运行(除非他们在创建套接字时检查/退出 - 但在这种情况下,为什么要额外工作?:-))
  • +1。接得好。我引用的代码是生产代码,事实上,如果它不能创建监听套接字,它会保释。
  • 感谢您的回答。所以似乎我必须使用 pids。
【解决方案2】:

您可以使用命名信号量,这是解决此问题的一种非常标准的方法。 您的程序调用 semctl() 来查找是否有任何活动的信号量,然后检查您是否可以运行。如果没有找到,则创建信号量。

操作系统处理进程被 kill -9 杀死并留下信号量的问题。 您需要为您的机器阅读 semctl 和 sem_open 的手册页,以了解该机制是什么 是。

【讨论】:

    猜你喜欢
    • 2023-01-16
    • 2017-11-14
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 2012-08-31
    • 1970-01-01
    • 2012-02-14
    • 1970-01-01
    相关资源
    最近更新 更多