我知道有类似的问题,但我认为我的情况有点不同。我需要检查子线程是否存活,如果它不是打印错误消息。子线程应该一直运行。所以基本上我只需要非阻塞pthread_join,在我的情况下没有竞争条件。可以杀死子线程,因此我无法在子线程完成时设置某种共享变量,因为在这种情况下不会设置它。
杀死子线程可以这样做:
编辑:好的,这个例子是错的,但我仍然确定有办法以某种方式杀死一个特定的线程。kill -9 child_pid
编辑:我的动机是在我的应用程序中实现另一层安全性,需要进行此检查。即使可以绕过这种检查,但这是另一回事。
编辑:假设我的应用程序是作为逆向工程学生的演示。他们的任务是破解我的申请。但我在子线程中放置了一些反黑客/反调试障碍。我想确保这个子线程保持活着。正如在一些评论中提到的那样 - 如果不弄乱父母就杀死孩子可能并不容易,所以也许这种检查不是必需的。主线程中也存在安全检查,但这次我需要将它们添加到另一个线程中以使主线程响应。
答案 0 :(得分:4)
杀死了什么,为什么那个东西无法表明线程已经死了?但即便如此,这听起来很可疑
如果您需要检查线程/进程是否处于活动状态,那么它几乎普遍存在设计错误 - 代码中的逻辑应该隐式处理这个问题。在你的编辑中,似乎你想要做一些线程被完全外部的东西杀死的可能性。
好吧,好消息。如果不让整个过程失效,就没有办法做到这一点。除了取消之外,线程非自愿死亡的所有方式都会杀死所有线程,但只能在同一进程中由其他内容触发。答案 1 :(得分:2)
kill(1)命令不会向某个线程发送信号,而是向整个process发送信号。仔细阅读signal(7)和pthreads(7)。
信号和线程不能很好地混合。根据经验,您不想同时使用它们。
顺便说一下,使用kill -KILL
或kill -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 theorem和Halting Problem:没有任何可靠和合理的static source code program analysis可以检查那)。如果其他东西(例如某些其他线程,或者甚至是您自己的代码中的错误代码)是例如任意修改你的主题的call stack,你得到undefined behavior,你可以非常scared。
在练习工具中,例如gdb
调试器,address and thread sanitizers,其他编译器instrumentation options,valgrind,可以帮助查找大多数此类错误,但有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...
}
但是,正如其他地方所说的那样,它并不是很有用,而且它作为任何类型的安全措施都非常薄弱。任何具有杀死线程权限的东西都可以阻止它运行而不会杀死它,或者让它运行任意代码,这样它就不会做你想要的。