检查pthread在Linux C中是否仍然存在

时间:2017-10-31 10:30:35

标签: c linux pthreads

我知道有类似的问题,但我认为我的情况有点不同。我需要检查子线程是否存活,如果它不是打印错误消息。子线程应该一直运行。所以基本上我只需要非阻塞pthread_join,在我的情况下没有竞争条件。可以杀死子线程,因此我无法在子线程完成时设置某种共享变量,因为在这种情况下不会设置它。

杀死子线程可以这样做:

  

kill -9 child_pid

编辑:好的,这个例子是错的,但我仍然确定有办法以某种方式杀死一个特定的线程。

编辑:我的动机是在我的应用程序中实现另一层安全性,需要进行此检查。即使可以绕过这种检查,但这是另一回事。

编辑:假设我的应用程序是作为逆向工程学生的演示。他们的任务是破解我的申请。但我在子线程中放置了一些反黑客/反调试障碍。我想确保这个子线程保持活着。正如在一些评论中提到的那样 - 如果不弄乱父母就杀死孩子可能并不容易,所以也许这种检查不是必需的。主线程中也存在安全检查,但这次我需要将它们添加到另一个线程中以使主线程响应。

3 个答案:

答案 0 :(得分:4)

杀死了什么,为什么那个东西无法表明线程已经死了?但即便如此,这听起来很可疑

如果您需要检查线程/进程是否处于活动状态,那么它几乎普遍存在设计错误 - 代码中的逻辑应该隐式处理这个问题。

在你的编辑中,似乎你想要做一些线程被完全外部的东西杀死的可能性。

好吧,好消息。如果不让整个过程失效,就没有办法做到这一点。除了取消之外,线程非自愿死亡的所有方式都会杀死所有线程,但只能在同一进程中由其他内容触发。

答案 1 :(得分:2)

kill(1)命令不会向某个线程发送信号,而是向整个process发送信号。仔细阅读signal(7)pthreads(7)

信号和线程不能很好地混合。根据经验,您不想同时使用它们。

顺便说一下,使用kill -KILLkill -9是错误的。接收过程没有机会处理SIGKILL信号。您应该使用SIGTERM ...

如果您想在多线程应用程序中处理SIGTERM,请阅读signal-safety(7)并考虑将一些pipe(7)设置为self(并在某些事件循环中使用poll(2))信号处理程序将write(2)。这个众所周知的技巧在Qt documentation中得到了很好的解释。您还可以考虑signalfd(2)特定于Linux的系统调用。

如果您考虑使用pthread_kill(3),您可能不应该在您的情况下(但是,使用0信号是有效但方式来检查线程是否存在) 。阅读一些Pthread tutorial。不要忘记pthread_join(3)pthread_detach(3)

  

子线程应该一直运行。

这是错误的方法。你应该知道子线程何时以及如何终止,因为你正在编写传递给pthread_create(3)的函数,你应该处理那里的所有错误情况并添加相关的清理代码(也许是同步)。所以子线程应该在你希望它运行时运行,并在结束时进行适当的清理操作。

还要考虑其他inter-process communication机制(例如socket(7)fifo(7) ...);它们通常比信号更合适,特别是对于多线程应用。例如,您可以将应用程序设计为某个专用Web或HTTP服务器(使用libonion或其他HTTP服务器库)。然后,您将使用Web浏览器或某些HTTP客户端命令(如curl)或HTTP客户端库(如libcurl)来驱动您的多线程应用程序。或者在您的应用程序中添加一些RPC功能,可能使用JSONRPC

(你对信号的推定使用非常糟糕,很可能是XY problem;考虑强烈使用更好的东西)

  

我的动机是在我的应用程序中实现另一层安全性

我根本不明白。信号和线程如何增加安全性?我猜你正在降低软件的安全性。

  

我想确保这个子线程保持活着状态。

你不能确定,除了编码好并避免错误(但要注意Rice's theoremHalting Problem:没有任何可靠和合理的static source code program analysis可以检查那)。如果其他东西(例如某些其他线程,或者甚至是您自己的代码中的错误代码)是例如任意修改你的主题的call stack,你得到undefined behavior,你可以非常scared

练习工具中,例如gdb调试器,address and thread sanitizers,其他编译器instrumentation optionsvalgrind,可以帮助查找大多数此类错误,但有No Silver Bullet

也许你想利用process isolation,但是你应该放弃多threading方法,并考虑一些multi-processing方法。根据定义,线程与相同virtual address space的其他线程共享大量资源(特别是它们的process)。所以你问题中提到的安全检查没有多大意义。我猜他们正在添加更多代码,但只是降低安全性(因为你会有更多错误)。

阅读像Operating Systems: Three Easy Pieces这样的教科书应该是值得的。

答案 2 :(得分:0)

您可以使用pthread_kill()检查线程是否存在。

  

<强>概要

#include <signal.h>

int pthread_kill(pthread_t thread, int sig);
     

<强>描述

     

pthread_kill()函数应请求传递信号   到指定的线程。

     

如在kill()中,如果sig为零,则应执行错误检查   但实际上不会发送任何信号。

这样的东西
int rc = pthread_kill( thread_id, 0 );
if ( rc != 0 )
{
    // thread no longer exists...
}
但是,正如其他地方所说的那样,它并不是很有用,而且它作为任何类型的安全措施都非常薄弱。任何具有杀死线程权限的东西都可以阻止它运行而不会杀死它,或者让它运行任意代码,这样它就不会做你想要的。

相关问题