[英]Thread cancellation (pthread) & C++
我正在用C ++編寫Linux程序,我想知道如何執行線程取消。
據我所知,當線程被取消時,在線程函數內部調用清理函數,強制線程函數退出。 這意味着兩件事:
我是對的,下面的代碼工作得很好嗎?
在下面的代碼中還有一個問題,當在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);
}
只有在清理方法中釋放已分配的對象時,才會調用析構函數。 否則,沒有。
是的,你在A部分的清理調用順序是正確的。
取消的線程堆棧未解除的斷言 - 導致本地對象的非破壞 - 與@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();
}
執行時,上面的程序表明當線程被取消時,確實調用了本地對象的析構函數:
$ ./a.out
Obj() called
cleanup() called
~Obj() called
$
使用NPTL的任何現代Linux發行版(實際上意味着任何運行2.6內核),NPTL將調用析構函數並使用偽異常展開堆棧。
事實上,NPTL通過實現所謂的強制堆棧展開來堅持它。 您可以使用catch(...)捕獲偽異常,但是如果您這樣做,則必須隨后重新拋出它,否則整個過程將被終止。
克里斯
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.