【问题标题】:unix socket creation then fork(), messaging gets mixed upunix 套接字创建然后 fork(),消息被混淆了
【发布时间】:2020-10-20 15:31:44
【问题描述】:

我目前正在尝试解决我创建process A 的问题,该process A 创建了一个Unix 套接字以连接到服务器进程。然后我分叉process A 并得到一个新的孩子process B。此时我有2个进程,具有重复的描述符等。当process B向服务器发送消息时,服务器处理消息然后将其发送回process A(但它应该回到process B )。我确信这是因为AB 是重复的,不知何故,从服务器的角度来看,Unix 套接字仍然是" process A socket",并且无论谁发送它们,所有消息都会返回到 A。

除了在进程 A 和 B 中断开和重新连接 post-fork 之外,还有什么方法可以解决这个问题? (进程AB 是主/从模式下的haproxy)?谢谢!

【问题讨论】:

  • 这是用于A和B之间的通信吗?
  • 对不起,不,我希望 A 与服务器通信并获取其响应,B 与服务器通信并返回其响应..
  • 原则上我希望进程 B 也能够接收来自服务器的回复,但是如果 B 正在发送请求,则 A 更有可能在这里赢得固有的比赛。 B 是否收到服务器为 A 的请求发送的回复?
  • 响应将返回到最先读取它的任何进程。如果两个进程同时在read() 中被阻塞,则无法预测哪一个会得到响应。
  • 你的怀疑是错误的。您不需要在父子节点中重新打开套接字。在fork() 之后,进程中的文件描述符引用相同的文件描述,这就是为什么任何一个进程都可以读取回复的原因。如果其中一个进程关闭其文件描述符,则文件描述不受影响,因为另一个进程仍然持有对它的引用。您只需在 一个 进程中关闭并重新打开连接。

标签: c linux fork haproxy unix-socket


【解决方案1】:

我目前正在尝试解决创建流程 A 的问题, 它创建一个 Unix 套接字来连接到服务器进程。我那时 fork 进程 A 并获得一个新的子进程 B。此时我有 2个进程,具有重复的描述符等。

你很快就忽略了这些细节,但我认为你并没有完全理解其中的意义。进程 B 确实继承了 fork() 中所有 A 的打开文件描述符的副本,但这并不意味着套接字本身被复制。那将如何运作?就远程对等点而言,只有一个连接。 B 继承的是整数文件描述符编号与操作系统维护的(非进程特定的)打开文件描述表之间的特定于进程的关联。因此,B 没有原始套接字的副本,而是同一个套接字

当进程 B 发送一个 消息到服务器,服务器处理消息然后发送 它返回到进程 A(但它应该返回到进程 B)。

远程服务器不知道 A 和 B。它只有一个连接,这就是它引导响应的地方。原则上,A 或 B 都可以获得它,但 A 始终赢得那场比赛是合理的。

我是 确定这是因为 A 和 B 是重复的,

是的,部分。

不知何故 Unix socket 从服务器的角度来看仍然是一个“进程 A 套接字”, 无论是谁发送的,所有消息都会返回给 A。

没有。见上文。

除了断开连接还有其他方法可以解决吗? 在进程 A 和 B 中重新连接 post-fork?

如果 B 重新连接是一个可行的解决方案,那么让它首先建立自己的连接,而不是从 A 继承一个呢?但是如果A需要代表B建立连接,那么A应该在fork B之后关闭连接,交给B独享。如果 A 需要自己与服务器的连接,那么它可以在分叉后建立一个新的连接。或者,如果自己的连接已经打开,A 可以在分叉之前建立第二个连接,并将那个连接交给 B,保留它自己的原始连接。在这种情况下,A 不仅想要关闭其 B 的连接副本,而且 B 也想要关闭其 A 的副本。

【讨论】:

  • 感谢您的详细回复..我一定会看看在fork之后不建立连接或重新连接的可行性..唯一的问题是应用程序是haproxy和我希望避免更改它,但这不是必需的,我会看看!
【解决方案2】:

我做了一些额外的研究,还有另一种方法可以做到这一点,我了解了 pthread_atfork(),它设置了由父级和子级在 fork 时调用的函数。我实际上使用这种机制来停止和启动孩子的网络功能,它工作!

https://linux.die.net/man/3/pthread_atfork

【讨论】:

    猜你喜欢
    • 2021-01-18
    • 2015-12-15
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多