6

我有一些代码会生成一个pthread尝试维护与远程主机的套接字连接的代码。如果连接丢失,它会尝试connect()在其套接字上使用阻塞调用重新连接。由于代码在单独的线程中运行,我并不真正关心它使用同步套接字 API 的事实。

也就是说,直到我的应用程序退出的时候。我想执行一些类似的有序关闭,所以我使用线程同步原语来唤醒线程并发出信号让它退出,然后pthread_join()在线程上执行 a 以等待它完成。connect()这很好用,除非当我命令关闭时线程处于调用中间。在这种情况下,我必须等待连接超时,这可能需要很长时间。这使得应用程序似乎需要很长时间才能关闭。

我想做的是以connect()某种方式中断对的呼叫。调用返回后,线程会注意到我的退出信号并干净地关闭。由于connect()是系统调用,我认为我可以使用信号故意中断它(从而使调用返回EINTR),但我不确定这是否是 POSIX 线程环境中的稳健方法。

有没有人对如何做到这一点有任何建议,无论是使用信号还是通过其他方法?请注意,connect()在一些我无法修改的库代码中调用已关闭,因此不能选择更改为非阻塞套接字。

4

1 回答 1

7

尝试close()套接字以中断connect()。我不确定,但我认为它至少可以在 Linux 上运行。当然,请注意正确同步,以便您只关闭()此套接字一次,或者第二次关闭()理论上可以关闭刚刚打开的不相关文件描述符。

编辑shutdown () 可能更合适,因为它实际上并没有关闭套接字。

或者,您可能想看看pthread_cancel()pthread_kill()。但是,我看不到在没有竞争条件的情况下使用这两者的方法。

我建议您放弃多线程服务器方法,转而使用事件驱动,例如使用epoll进行事件通知。通过这种方式,您可以避免所有这些非常基本的问题,这些问题对于线程来说变得非常困难,例如正确关闭。您可以随时自由地做任何您想做的事情,例如安全地关闭套接字并且再也不会收到他们的消息。

另一方面,如果在您的工作线程中执行非阻塞connect()并通过 epoll_pwait() (或 ppoll( )pselect();注意p)获得通知,您可能能够避免相关的竞争条件与信号。

于 2012-06-09T16:29:03.093 回答