我正在努力将一些相对简单的networking代码从Unix移植到Windows。
简而言之,有一个pipe理所有networkingstream量的networking线程。 这个单线程大部分时间都在poll()
中(我已经将它转换为select()
,在Windows中),networking线程只有在有传入的networking数据时才会唤醒。 当客户端命令到达时,networking线程将该命令触发到工作线程,以便在后端实际执行工作,然后返回到侦听更多传入命令。 命令是asynchronous的 – 多个命令可以进入一个套接字,一个接一个。 在任何时候,在一个连接上可以有几十个优秀的命令,所有这些命令都在不同的工作线程中工作。
问题是,当工作线程想要发送响应数据时,在工作线程尝试发送结果时,networking线程可能在poll()
内部处于睡眠状态。 networking线程必须等待poll()
超时(或接收到另一个数据包),才会注意到有新的出站数据排队等待发送。
在unix环境下,我通过在poll()
监视的描述符中包含一个pipe道来处理这个问题,当一个工作线程有出站数据发送时,它还将一个数据字节写入pipe道来唤醒networking线程。 但是WinSock似乎只支持在套接字上等待,所以这种方法在Windows中不适用于我。 有没有什么方法可以让我在Windows上使用WinSock抢救这个体系结构(这样我就可以在不同的平台之间共享大部分代码),还是别无select,只能编写一个自定义的networking服务器实现来在Windows上使用?
感谢您的任何build议!
只有两种可能性,而且都不需要你提出的解决方案:
1)您已经尝试在此连接上发送数据,并且操作系统的发送队列已满。 在这种情况下,不需要中止select
或poll
。 无论如何,您现在都无法在连接上写信,您将尽快退出select
或自动poll
。
2)您目前没有尝试在此连接上发送数据。 在这种情况下,也不需要中止select
或poll
。 现在只需要在工作线程中写入数据。 (套接字是非阻塞的,对不对?)如果你不写所有的数据,那只是因为操作系统的发送队列已满,在这种情况下通常不会急于写入(设置合理的超时select
呼叫)。
你真的不应该使用Windows上的select
。 这只是一个憎恶,只是为了兼容性。 如果你打算“真正”支持Windows,你不应该把它做成二等的。 网络I / O是真的必须是平台特定的。
而不是在Windows上使用select
,如果使用IO完成端口并发布读取缓冲区,则会得到明显更好的结果。 在IOCP模型下,可以使用PostQueuedCompletionStatus
API与服务于IOCP的线程进行通信。