0

我有一个将日志输出显示到标准输出的程序。

因此,如果我打开一个到我的目标 linux 的 telnet 会话,然后在这个 telnet 会话上启动我的程序,那么我将在我的 telnet 会话上显示日志消息。

在我的程序中,我运行了一个小型 http 服务器。现在,如果我更改目标 linux 的 IP 地址,然后重新启动接口(http 服务器将自动重新启动,因为我使用 netlink 检测到 IP 地址的更改)然后我将关闭 telnet 会话并重定向 stdout 消息到我的 http 服务器打开的套接字,我将锁定日志消息的 printf。

我尝试使用 select 来检测这个锁,但没有成功:How to use select with stdout?

在进入 prinf 之前选择返回成功(锁定)

有什么建议可以避免这个问题吗?

4

1 回答 1

0

如果我理解正确的话,由于IP地址的变化,运行HTTP服务器的telnet会话(你为什么不使用SSH??)会被破坏。

如果程序继续向这个会话(这是它的标准输出)写入数据,之后会发生什么,首先写入将成功,因为系统缓冲数据,然后最终写入将阻塞(而不是“锁定”)。最后,TCP 连接将超时,写入将返回错误。TCP 会话超时可能需要很长时间,也可能不需要很长时间,但最终会。

如果您想避免阻塞(例如,如果您的应用程序是事件驱动的并且不能阻塞),您可以使您的日志输出代码使用非阻塞写入标准输出。您将需要使用fcntl将 stdout 更改为非阻塞,并且您可能需要完全避免使用 stdio,因为 stdio 不是为使用非阻塞输出而设计的。您必须实现自己的缓冲并直接写入文件描述符 1。

您还提到要在标准输出日志损坏后登录到 HTTP 连接。你也可以这样做(一旦你得到一个写入标准输出的错误就会触发)但它会做更多的工作。您必须在应用程序内部管理日志缓冲区,直到 HTTP 客户端连接并请求它。如果日志太大,您还需要添加丢弃日志的规定,以防没有 HTTP 客户端连接。所有这些都超出了 SO 问题的范围......

于 2013-02-20T18:52:13.097 回答