【问题标题】:Unlink/cleanup unix socket only if it's still owned by process仅当它仍归进程所有时才取消链接/清理 unix 套接字
【发布时间】:2016-02-25 15:44:06
【问题描述】:

第一次使用 Unix 域套接字,现在我正在尝试实现清理部分。

创建侦听套接字时的一般建议是首先尝试取消链接所需的套接字路径,然后调用绑定,这已经有点难看了。虽然您可能应该确保您的进程只运行一次,但我正在尝试为由于某种原因它将启动两次的情况做好准备。对于服务本身来说,这无关紧要:第一个实例的套接字与第二个实例取消链接,因此无法访问,浪费了一些 RAM,但不会造成任何伤害。但是我将如何实施在这种情况下有效的清理?简单的做

close(sockFd);
unlink(sockPath);

会导致这样的情况,如果第一个进程退出而第二个进程仍在运行,它实际上会从文件系统中删除第二个进程的套接字。繁荣,没有服务。

我只能想到一些丑陋的 hack,它们不是原子的,所以仍然可能把事情搞砸,所以我希望有一个更好的范例来防止在这种情况下结束。像 funlink(sockFd) 这样的东西会很好。否则我只能求助于从不清理套接字,这不是世界末日,但对我来说感觉很乱。

抽象域套接字看起来很有希望(尽管它现在将我绑定到 Linux),但不幸的是它们似乎不支持权限,这在我的情况下是一个要求。

【问题讨论】:

  • 这是我通常做的,以避免 2 个进程试图在同一个 unix 域套接字上侦听。我做的第一件事是尝试连接到套接字。如果连接正常,那么已经有一个监听器在运行,我会退出。否则,我将允许进程继续并在套接字上侦听。清理应该很容易,因为您确定您只有 1 个侦听器。
  • 正确的方法是尝试绑定到套接字,如果套接字已在使用中,您将得到EADDRINUSE。现在您知道另一个进程已经在监听它,您可以退出。
  • @alvits 我想你得到 EADDRINUSE 即使第一个进程退出并且文件系统中只剩下挥之不去的套接字,所以这并不比无条件地删除套接字更好在启动时,但绑定之前的连接可能是一个选项;我会尝试一下...

标签: c linux unix-socket


【解决方案1】:

在对套接字进行任何操作之前,您可以使用一个单独的锁定文件,您的应用程序使用flock(..., LOCK_EX) 锁定该文件。只要所有应用程序实例都同意使用哪个锁文件,您就是安全的,并且flock() 是原子的。 flock() 的清理没有问题,因为当进程终止时,锁会被释放。

【讨论】:

    猜你喜欢
    • 2011-08-20
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 2017-01-31
    • 1970-01-01
    相关资源
    最近更新 更多