[英]Thread cancellation (pthread) & C++
I'm writing MT program for Linux in C++ and I want to know how thread cancellation is performed. 我正在用C ++编写Linux程序,我想知道如何执行线程取消。
As far as I understand when thread is cancelled cleanup functions are called inside thread's function and the thread's function is forced to exit. 据我所知,当线程被取消时,在线程函数内部调用清理函数,强制线程函数退出。 This mean two things:
这意味着两件事:
Am I right and code below ill work just fine? 我是对的,下面的代码工作得很好吗?
One more question in code below, when thread is cancelled somewhere in SECTION A , second_thread_cleanup_function() will be called first, right? 在下面的代码中还有一个问题,当在SECTION A的某处取消线程时, second_thread_cleanup_function()将首先被调用,对吗?
class SomeObject
{
public:
~SimpleObject (void); // <- free dynamically allocated memory
void finalize (void);
// ...
}
void first_thread_cleanup_function (void* argument)
{
SomeObject* object (argument);
object->finalize ();
}
void second_thread_cleanup_function (void* argument)
{
// ... do something ...
}
void* thread_function (viod* argument)
{
SomeObject object;
pthread_cleanup_push (first_thread_cleanup_function, &object);
// ... some code ...
pthread_cleanup_push (second_thread_cleanup_function, NULL);
// ... SECTION A ...
pthread_cleanup_pop (0);
// .. some code ...
pthread_cleanup_pop (1);
}
Destructors will only be called assuming you free allocated objects in the cleanup methods. 只有在清理方法中释放已分配的对象时,才会调用析构函数。 Otherwise, no.
否则,没有。
And yes, you have the order of cleanup calls in section A correct. 是的,你在A部分的清理调用顺序是正确的。
The assertion that a cancelled thread's stack is not unwound -- resulting in the non-destruction of local objects -- is inconsistent with the assertion by @Chris that the thread's stack is unwound and with the following counter-example: 取消的线程堆栈未解除的断言 - 导致本地对象的非破坏 - 与@Chris的断言不一致,即线程的堆栈被解开并且具有以下反例:
#include <climits>
#include <iostream>
#include <pthread.h>
#include <thread>
#include <unistd.h>
class Obj {
public:
Obj() { std::clog << "Obj() called\n"; }
~Obj() { std::clog << "~Obj() called\n"; }
};
static void cleanup(void* arg) {
std::clog << "cleanup() called\n";
}
static void run() {
Obj obj{}; // Local object
pthread_cleanup_push(cleanup, nullptr);
::pause(); // Thread cancelled here
pthread_cleanup_pop(1);
}
int main(int argc, char **argv) {
std::thread thread([]{run();});
::sleep(1);
::pthread_cancel(thread.native_handle());
thread.join();
}
When executed, the above program indicates that the local object's destructor is, indeed, called when the thread is cancelled: 执行时,上面的程序表明当线程被取消时,确实调用了本地对象的析构函数:
$ ./a.out
Obj() called
cleanup() called
~Obj() called
$
With any modern linux distribution using NPTL (which in practice means any running a 2.6 kernel), NPTL will call destructors and unwind the stack with a pseudo-exception. 使用NPTL的任何现代Linux发行版(实际上意味着任何运行2.6内核),NPTL将调用析构函数并使用伪异常展开堆栈。
In fact NPTL insists on it, by implementing what it calls forced stack unwinding. 事实上,NPTL通过实现所谓的强制堆栈展开来坚持它。 You can catch the pseudo-exception with catch(...), but if you do so you must subsequently rethrow it or the whole process will be terminated.
您可以使用catch(...)捕获伪异常,但是如果您这样做,则必须随后重新抛出它,否则整个过程将被终止。
Chris 克里斯
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.