使用select检测服务器套接字关闭

使用select检测服务器套接字关闭,c,linux,sockets,C,Linux,Sockets,我有一个简单的套接字服务器,在linux和Windows上用C实现,很难完全关闭它 它创建一个套接字,绑定它,然后调用listen。然后,它使用select循环以检测新的连接,并在任何当前连接的客户端套接字上执行读取活动。客户端关闭套接字很好,这会唤醒select,我遇到的问题是完全关闭了循环。我天真地从另一个线程关闭了服务器套接字(我正在侦听和接受的套接字),或者响应信号或Ctrl-C,但这并没有唤醒select,这让我感到惊讶 如果需要的话,我可以使用self-pipe技巧等待select-

我有一个简单的套接字服务器,在linux和Windows上用C实现,很难完全关闭它

它创建一个套接字,绑定它,然后调用listen。然后,它使用select循环以检测新的连接,并在任何当前连接的客户端套接字上执行读取活动。客户端关闭套接字很好,这会唤醒select,我遇到的问题是完全关闭了循环。我天真地从另一个线程关闭了服务器套接字(我正在侦听和接受的套接字),或者响应信号或Ctrl-C,但这并没有唤醒select,这让我感到惊讶

如果需要的话,我可以使用self-pipe技巧等待select-up(创建一个fifo,并将读取端也包括在select列表中,然后在我想关机时写入),但考虑到代码的结构,这将不会非常方便。 我只是想知道这是否是预期的行为,当我关闭服务器套接字时,我是否会期望我的select唤醒。它在Windows上确实是这样工作的


谢谢。

从另一个线程关闭套接字/文件描述符是个糟糕的主意,因为它容易出现争用情况

选择
呼叫被信号中断。您可以在
select
线程中使用自管道技巧检测
SIGINT
,并根据需要关闭套接字


或者,信号处理程序不必通过管道传递信号号,只需设置一个全局
sigaomatic\u t
变量,当
pselect
线程被信号中断时,该变量将进行检查。在这种情况下,必须始终阻止
SIGINT
,除非在
pselect
调用中。

您的侦听套接字是否在select()的read fd set中?你能简单地定位一个全局变量并用pthread_kill向select线程发送一个信号吗?给我带来问题的实际环境是我的测试环境,当测试在主线程上运行时,我显然必须在一个线程上运行服务器,然后我想在测试完成后关闭服务器。我必须尝试并解决如何将管道干净地包含到代码结构中,以便更干净地执行此操作。谢谢。不幸的是,self-pipe技巧只适用于UNIX,而在Windows上,select只适用于套接字。我想最可移植的解决方案是创建一个端口并将其绑定到临时端口上的localhost,然后连接到该端口并将其用作此类事情的控制端口,因此使用自管道套接字而不是fifo。但是感觉很沉重。@TomQuarendon:“我想关闭服务器”,所以您的实现没有提供任何关闭服务器的功能?@TomQuarendon我会检查Windows
select
是否可以使用。@TomQuarendon:那么您最好不要使用
select()
。在*Nix上使用
(e)poll()
,在Windows上使用
WSAEventSelect()
+
WSAWaitForMultipleEvents()
(在Windows上,每个套接字都有一个
WSAEVENT
,关闭时有一个
WSAEVENT
,这将是在Windows上以最小的努力实现自管道技巧的最接近的方法)。