【问题标题】:send() on UNIX domain socket (PF_UNIX) fails with ENOBUFS error [closed]UNIX域套接字(PF_UNIX)上的send()失败并出现ENOBUFS错误[关闭]
【发布时间】:2019-02-01 18:09:56
【问题描述】:

我有一个进程创建一个新的子进程来处理某些任务。主进程还创建了一个子线程,用于一项特定任务。这些进程和线程通过 UNIX 域套接字进行通信。

由于某种原因,子进程卡住了,它仍然处于 umtx 状态。因此,每当主进程尝试向仍处于等待状态并等待子进程退出的子线程发送一些数据时,都不会响应。

最终,父套接字的 tx 队列不断累积消息并变满。这会导致 send() 失败并出现 ENOBUFS 错误。

我该如何解决这个问题?

【问题讨论】:

  • @hellow :感谢您的即时回复。在 send() 之前添加以下 sn-p 是否正确? if (fflush((FILE *)&communication_sockets[0])) { printf("fflush failed"); }
  • 我不相信这是为数据报套接字定义或可能的,至少从发送端开始。如果我想“刷新”基于数据报的协议,那么我可能会在协议中添加一个“刷新”交换,其中发送方向对等方发出“刷新通信”消息。收到后,对等端读取并丢弃所有待处理的数据报。等待很长时间,再次读取并丢弃所有挂起的数据报,然后向发起者发送“刷新完成”回复。
  • @pseudonym:您正在使用 Unix 域数据报套接字,它保留了消息边界。这意味着写入的数据(send())不能与以前写入的数据混合,也不能与将来写入的任何数据混合;内核负责确保这一点。但是,写端无法控制读端已经拥有的东西;发送什么,发送什么,它不在发送者的控制范围内。 (如果不是这样,恶意程序会尝试“取消发送”他们的行为报告......)因此,你似乎试图做的事情对我来说毫无意义。
  • AFIK,使用阻塞数据报 AF_UNIX 套接字,send() 将阻塞,直到数据报存储到(目标)队列。如果队列中有空间,则不会阻塞。因此,没有必要刷新输出队列,因为没有任何输出队列。
  • 大家好,我实际上已经改变了问题来描述我的确切问题场景。请帮帮我。

标签: c sockets posix


【解决方案1】:

我该如何解决这个问题?

找出您的子进程卡住的原因并防止这种情况发生,然后套接字队列将不会运行满。这就是你整个问题的原因,不是吗?

您还想如何克服它?给 IPC 套接字一个巨大的缓冲区只会让它积累更多的数据,但最终它会以同样的方式失败。所以这不会解决任何问题,只会拖延问题。

还要以有意义的方式处理错误,例如尝试在一段时间后再次发送消息,如果再次失败,则终止子进程。这样,当您的子进程失败时,您的主进程至少可以恢复。

最后但同样重要的是:您不应该使用 UNIX 套接字进行线程间通信。它旨在用于进程间通信。在线程间使用它可能会产生不良影响,因此强烈建议您这样做,除非您出于测试目的这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    相关资源
    最近更新 更多