简体   繁体   English

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

[英]Check if pthread is still alive in Linux C

I know similar questions have been asked, but I think my situation is little bit different. 我知道有人问过类似的问题,但我认为情况略有不同。 I need to check if child thread is alive, and if it's not print error message. 我需要检查子线程是否处于活动状态,以及是否未显示错误消息。 Child thread is supposed to run all the time. 子线程应该一直运行。 So basically I just need non-block pthread_join and in my case there are no race conditions. 所以基本上我只需要非阻塞pthread_join,就我而言,没有竞争条件。 Child thread can be killed so I can't set some kind of shared variable from child thread when it completes because it will not be set in this case. 子线程可以被杀死,因此我无法在子线程完成时设置某种共享变量,因为在这种情况下将不会设置该共享变量。

Killing of child thread can be done like this: 子线程的杀死可以这样完成:

kill -9 child_pid 杀死-9 child_pid

EDIT: alright, this example is wrong but still I'm sure there exists way to kill a specific thread in some way. 编辑:好的,这个例子是错误的,但是我仍然确定存在以某种方式杀死特定线程的方法。

EDIT: my motivation for this is to implement another layer of security in my application which requires this check. 编辑:我这样做的动机是在我的应用程序中实现另一层安全性,这需要进行此检查。 Even though this check can be bypassed but that is another story. 即使可以绕过此检查,但这是另一回事。

EDIT: lets say my application is intended as a demo for reverse engineering students. 编辑:可以说我的应用程序旨在作为反向工程专业学生的演示。 And their task is to hack my application. 他们的任务是破解我的应用程序。 But I placed some anti-hacking/anti-debugging obstacles in child thread. 但是我在子线程中设置了一些反黑客/反调试的障碍。 And I wanted to be sure that this child thread is kept alive. 而且我想确保此子线程保持活动状态。 As mentioned in some comments - it's probably not that easy to kill child without messing parent so maybe this check is not necessary. 正如一些评论中提到的那样-在不弄乱父母的情况下杀死孩子可能不是那么容易,所以也许这项检查是不必要的。 Security checks are present in main thread also but this time I needed to add them in another thread to make main thread responsive. 安全检查也存在于主线程中,但是这一次我需要将其添加到另一个线程中以使主线程响应。

killed by what and why that thing can't indicate the thread is dead? 被什么杀死了,为什么那东西不能表明线程已死? but even then this sounds fishy 但这听起来还是很可疑

it's almost universally a design error if you need to check if a thread/process is alive - the logic in the code should implicitly handle this. 如果您需要检查线程/进程是否存在,这几乎是一个设计错误-代码中的逻辑应隐式处理此错误。

In your edit it seems you want to do something about a possibility of a thread getting killed by something completely external. 在您的编辑中,您似乎想对某个线程被完全外部的事物杀死的可能性进行某些处理。

Well, good news. 好吧,好消息。 There is no way to do that without bringing the whole process down. 不降低整个过程是不可能的。 All ways of non-voluntary death of a thread kill all threads in the process, apart from cancellation but that can only be triggered by something else in the same process. 线程的所有非自愿死亡方式都会杀死进程中的所有线程,除了取消之外,但这只能由同一进程中的其他事件触发。

The kill(1) command does not send signals to some thread, but to a entire process . kill(1)命令不会将信号发送到某个线程,而是发送到整个进程 Read carefully signal(7) and pthreads(7) . 仔细阅读signal(7)pthreads(7)

Signals and threads don't mix well together . 信号和线程混合不好 As a rule of thumb, you don't want to use both. 根据经验,您不想同时使用两者。

BTW, using kill -KILL or kill -9 is a mistake. 顺便说一句,使用kill -KILLkill -9是一个错误。 The receiving process don't have the opportunity to handle the SIGKILL signal. 接收过程没有机会处理SIGKILL信号。 You should use SIGTERM ... 您应该使用SIGTERM ...

If you want to handle SIGTERM in a multi-threaded application, read signal-safety(7) and consider setting some pipe(7) to self (and use poll(2) in some event loop) which the signal handler would write(2) . 如果要在多线程应用程序中处理SIGTERM ,请阅读signal-safety(7)并考虑将一些pipe(7)设置为self(并在某些事件循环中使用poll(2) ),该信号处理程序将编写该信号(2 ) That well-known trick is well explained in Qt documentation . Qt文档中很好地解释了这一众所周知的技巧。 You could also consider the signalfd(2) Linux specific syscall. 您还可以考虑使用signalfd(2) Linux特定的syscall。

If you think of using pthread_kill(3) , you probably should not in your case (however, using it with a 0 signal is a valid but crude way to check that the thread exists). 如果您考虑使用pthread_kill(3) ,那么您可能不应该这样做(但是,将其与0信号一起使用是检查该线程是否存在的有效但粗略的方法)。 Read some Pthread tutorial . 阅读一些Pthread教程 Don't forget to pthread_join(3) or pthread_detach(3) . 不要忘记使用pthread_join(3)pthread_detach(3)

Child thread is supposed to run all the time. 子线程应该一直运行。

This is the wrong approach . 这是错误的做法 You should know when and how a child thread terminates because you are coding the function passed to pthread_create(3) and you should handle all error cases there and add relevant cleanup code (and perhaps synchronization). 您应该知道子线程的终止时间和终止方式,因为您正在编码传递给pthread_create(3)的函数,并且应该在那里处理所有错误情况并添加相关的清除代码(也许还需要同步)。 So the child thread should run as long as you want it to run and should do appropriate cleanup actions when ending. 因此,子线程应一直运行,只要您希望它运行即可,并且在结束时应执行适当的清理操作。

Consider also some other inter-process communication mechanism (like socket(7) , fifo(7) ...); 还考虑其他一些进程间通信机制(例如socket(7)fifo(7) ...); they are generally more suitable than signals, notably for multi-threaded applications. 它们通常比信号更适合,特别是对于多线程应用程序。 For example you might design your application as some specialized web or HTTP server (using libonion or some other HTTP server library). 例如,您可以将应用程序设计为某些专用的Web或HTTP服务器(使用libonion或其他HTTP服务器库)。 You'll then use your web browser, or some HTTP client command (like curl ) or HTTP client library like libcurl to drive your multi-threaded application. 然后,您将使用Web浏览器或某些HTTP客户端命令(例如curl )或HTTP客户端库(例如libcurl)来驱动多线程应用程序。 Or add some RPC ability into your application, perhaps using JSONRPC . 或者,可以使用JSONRPC在您的应用程序中添加一些RPC功能。

(your putative usage of signals smells very bad and is likely to be some XY problem ; consider strongly using something better) (您对信号的假定用法闻起来很不好,可能是一些XY问题 ;请考虑使用更好的方法)

my motivation for this is to implement another layer of security in my application 我这样做的动机是在应用程序中实现另一层安全性

I don't understand that at all. 我一点都不明白。 How can signal and threads add security? 信号和线程如何增加安全性? I'm guessing you are decreasing the security of your software. 我猜您正在降低软件的安全性。

I wanted to be sure that this child thread is kept alive. 我想确保此子线程保持活动状态。

You can't be sure, other than by coding well and avoiding bugs (but be aware of Rice's theorem and the Halting Problem : there cannot be any reliable and sound static source code program analysis to check that). 您无法确定,只能通过编码良好并避免错误来避免(但要注意赖斯定理暂停问题 :无法进行任何可靠且可靠的静态源代码程序分析来进行检查)。 If something else (eg some other thread, or even bad code in your own one) is eg arbitrarily modifying the call stack of your thread, you've got undefined behavior and you can just be very scared . 如果有其他事情(例如某个其他线程,甚至是您自己的错误代码)例如在任意修改线程的调用堆栈 ,那么您的行为就不确定 ,您可能会非常害怕

In practice tools like the gdb debugger, address and thread sanitizers , other compiler instrumentation options , valgrind , can help to find most such bugs, but there is No Silver Bullet . 实践中,诸如gdb调试器, 地址和线程清理器之类的工具 ,其他编译器检测选项 valgrind可以帮助发现大多数此类bug,但是没有Silver Bullet

Maybe you want to take advantage of process isolation , but then you should give up your multi- threading approach, and consider some multi-processing approach. 也许您想利用进程隔离的优势,但是您应该放弃多线程方法,而考虑一些多处理方法。 By definition, threads share a lot of resources (notably their virtual address space ) with other threads of the same process . 根据定义,线程与同一进程的其他线程共享许多资源(尤其是虚拟地址空间 )。 So the security checks mentioned in your question don't make much sense. 因此,您的问题中提到的安全检查没有多大意义。 I guess that they are adding more code, but just decrease security (since you'll have more bugs). 我想他们会添加更多的代码,但是会降低安全性(因为您将有更多的错误)。

Reading a textbook like Operating Systems: Three Easy Pieces should be worthwhile. 阅读诸如《 操作系统:三篇简单的书》这样的教科书应该值得。

You can use pthread_kill() to check if a thread exists. 您可以使用pthread_kill()检查线程是否存在。

SYNOPSIS 概要

 #include <signal.h> int pthread_kill(pthread_t thread, int sig); 

DESCRIPTION 描述

The pthread_kill() function shall request that a signal be delivered to the specified thread. pthread_kill()函数应请求将信号传递到指定线程。

As in kill(), if sig is zero, error checking shall be performed but no signal shall actually be sent. 与kill()中一样, 如果sig为零,则应执行错误检查,但实际上不发送任何信号。

Something like 就像是

int rc = pthread_kill( thread_id, 0 );
if ( rc != 0 )
{
    // thread no longer exists...
}

It's not very useful, though, as stated by others elsewhere, and it's really weak as any type of security measure. 但是,正如其他地方的其他人所说的那样,它不是很有用,并且它作为任何类型的安全措施都确实很弱。 Anything with permissions to kill a thread will be able to stop it from running without killing it, or make it run arbitrary code so that it doesn't do what you want. 具有杀死线程权限的任何对象都可以在不杀死线程的情况下停止其运行,或者使该线程运行任意代码,从而使其无法执行所需的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM