杀死具有套接字的单独线程

Posted

技术标签:

【中文标题】杀死具有套接字的单独线程【英文标题】:killing a separate thread having a socket 【发布时间】:2010-04-13 14:18:41 【问题描述】:

我有一个单独的线程ListenerThread 有一个套接字监听某个远程服务器广播的信息。这是在我需要开发的一个类的构造函数中创建的。

由于要求,一旦启动单独的线程,我需要避免主线程上的任何阻塞功能。 一旦到了调用我的类的析构函数的地步,我就无法在侦听器线程上执行连接,所以我唯一能做的就是杀死它。

我的问题是:

    传递给 thead 的函数分配的网络资源会发生什么变化?套接字是否正确关闭或者可能有一些待处理的事情? (最担心这个)

    这个过程是否足够快,即线程是否被杀死以便立即中断?

    我正在使用 Linux ...我可以检查什么命令或什么来确保没有未决的网络资源或操作系统出现问题

非常感谢您的帮助

问候 MNSTN

注意:我在 C++ 中使用 boost::thread

【问题讨论】:

【参考方案1】:

    网络资源属于进程,不属于线程,所以socket还是打开的。

    boost::thread 没有 kill 方法。你只能 打断它。效果不是 立即并取决于操作系统 调度程序。

    用于查看哪些网络资源 一个进程持有结帐lsofnetstat(8) 带有-p 选项。

您描述的阻塞套接字的停止信号问题通常通过self-pipe trick 解决。

【讨论】:

谢谢尼古拉!你能确认即使我使用 PTHREAD ,我在使用 pthread_cancel 或 pthread_kill 或其他功能时也会遇到同样的问题吗?由于操作系统中的网络资源,必须应用相同的自管道技巧,对吧? 我不会说 必须,但它的工作原理是一样的(boost::thread 在 Unix 上使用 PThreads 实现。)【参考方案2】:

当你杀死一个线程时,你不能确定它拥有什么资源。例如,它可能持有堆互斥锁;如果您杀死线程,互斥锁将保持锁定状态,并且(在您的进程中)没有人能够分配动态内存。

通过和平的共识来做这些事情比通过武力来做这些事情要好得多。 只需添加一种方法来向您的线程发出不再需要它的信号。它可以是boost::condition。线程将检查此条件并在收到信号时停止。

【讨论】:

嗨,ATZZ。谢谢您的答复。在我的代码中实际上我根本没有任何互斥锁..你认为使用 boost::condition 比使用 boost::thread::interrupt() 杀死线程更好吗? 我不确定 boost::thread 是否有类似的东西,但是 pthreads API 支持 pthread_atexit() 专门作为线程在线程终止时释放它正在管理的资源的一种方式。将 pthread_atexit() 视为类似于线程的“最后遗嘱和遗嘱”。 @Chris Cleeland -- 你的意思是 pthread_cleanup_push()?它可以帮助您显式控制资源,但是对于您隐式使用的资源(在您使用的库的实现中)或系统资源呢? @user311906 -- 如果你的线程正在使用系统调用,它可以获取和释放一些内部系统资源。 boost::thread::interrupt 应该是安全的,但它与手动管理的 boost::condition 基本相同。它只能在“中断点”被检测到,并且不会中断在系统调用中阻塞的线程。 你是正确的关于 pthread_cleanup_push(); pthread_atexit() 必须是早期或替代实现的一部分。但是,要回答您的问题,您不能对您不拥有的资源做任何事情。套接字,OTOH,是您拥有的资源。与 boost::thread::interrupt 一样,pthread_cancel() 仅在安全取消点中断。手动管理线程的生命周期通常无法达到我们真正想要的效果。

以上是关于杀死具有套接字的单独线程的主要内容,如果未能解决你的问题,请参考以下文章

如何杀死java上的线程? [复制]

如何在单独的线程中处理套接字请求,线程似乎阻塞了主进程

断开连接后正确杀死asio steady_timer

为啥我的客户端会杀死我的服务器?

在触发on之后杀死特定的侦听器

为啥不创建单独的线程?