【问题标题】:reopen a connection on same port results in bad file descriptor handle在同一端口上重新打开连接会导致文件描述符句柄错误
【发布时间】:2021-02-13 22:20:56
【问题描述】:

我有一个 proc 在端口 2600 上生成一个子进程。它使用句柄 6 连接到该进程,提取一些数据,终止该进程,然后在同一端口上启动另一个子进程,我连接到它,什么时候我尝试在句柄上运行我的命令,但出现以下错误:

'Cannot write to handle 6. OS reports: Bad File Descriptor

进程正在运行,我可以手动连接到它并获取我的数据。我有一个跟踪连接的表,我可以看到第二次产生子进程的句柄也是 6。关于为什么会发生这种情况的任何建议?

更新:只是为了说清楚。当我关闭句柄时,我使用“exit 1”向 proc 发送一条异步消息。这可能是在我打开与它的连接之前该进程没有被杀死,之后被杀死,然后我认为它的新进程只是旧进程的垃圾句柄,现在已经失效的进程?

更新:我在发送“exit 1”后刷新了句柄,新进程似乎开始正常。我可以看到新进程在进程上运行(它们有不同的名称)

更新:即使连接成功,句柄也不会添加到 .z.W。所以句柄不会出现在 .z.W

更新:发现问题。我正在使用的 .IPC.SCON 函数,我认为它只是一个简单的错误陷阱包装器......具有检查相同 hst:prt 的缓存句柄表并获取该句柄而不是打开另一个句柄的逻辑。因为我的进程在同一个主机:端口上运行,它使用旧的缓存句柄而不是再次打开它。谢谢大家的帮助。

【问题讨论】:

  • 在发送“exit 1”并刷新传出的异步之后,可能值得在父端添加一个明确的hclose handle
  • 还是没有运气。句柄似乎没有添加到.z.W。使用相同的端口可能是个问题?也许端口没有及时释放以进行新连接。还不知道。
  • 我明白了。你是在使用 vanilla hopen 函数还是使用某种包装器/保护评估?
  • 用于打开我正在使用的连接 @[hopen;x;0Ni] 其中 x 是 (host:port;timeout)
  • 你确定受保护的 eval 没有返回 null int 吗?您是否在第二次调用希望后修改句柄变量?我在下面的回复中添加了另一个更新,这是怎么回事?出于调试目的,我会暂时将上面的内容更改为@[hopen;x]

标签: kdb


【解决方案1】:

您使用的是什么版本的 kdb?您可以毫无问题地运行以下命令吗?

KDB+ 4.0 2020.08.28 Copyright (C) 1993-2020 Kx Systems

q)system"q -p 5000";system"sleep 1";h:hopen 5000;0N!h".z.i";neg[h](exit;0)
4475i
q)system"q -p 5000";system"sleep 1";h:hopen 5000;0N!h".z.i";neg[h](exit;0)
4481i
q)system"q -p 5000";system"sleep 1";h:hopen 5000;0N!h".z.i";neg[h](exit;0)
4487i

更新:没有看到您的代码或执行顺序,很难确定问题所在。如果在您尝试启动新进程之前该进程没有终止,您将看到 Address already in use 错误。如果在您尝试连接时进程未启动,您会看到 'hop 错误,这意味着希望失败。 此外,异步消息不会立即发送,因此根据代码的执行顺序,您可能需要刷新异步“退出”消息,但就像我提到的,如果在您尝试启动另一个子进程时原始子进程仍在运行,你会遇到地址冲突

更新 2:根据我上面的评论

q)system"q -p 5000"; system"sleep 1"; h:@[hopen;(`::5000;2000);0Ni]; 0N!h".z.i"; neg[h](exit;1)
4365i
q)system"q busy.q -p 5000"; system"sleep 1"; @[hopen;(`::5000;2000);0Ni]; h".z.i"    // hopen times out + handle variable not amended
'Cannot write to handle 4. OS reports: Bad file descriptor
  [0]  system"q busy.q -p 5000"; system"sleep 1"; @[hopen;(`::5000;2000);0Ni]; h".z.i"    // hopen times out + handle variable not amended
                                                                               ^
q).z.W
q)

【讨论】:

  • 运行 3.6 l64
【解决方案2】:

我认为您在 UPDATE 中写的内容是正确的。该进程正在尝试在您的新进程在其上运行之前连接到该端口。 我认为最好的选择是让新启动的进程启动与父进程的连接,这样你就知道它将运行并且不必引入任何睡眠。 其他选择是尝试在计时器上重新连接,一旦成功连接,将其从计时器中删除并继续您正在尝试做的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    相关资源
    最近更新 更多