簡體   English   中英

線程取消(pthread)和C ++

[英]Thread cancellation (pthread) & C++

我正在用C ++編寫Linux程序,我想知道如何執行線程取消。

據我所知,當線程被取消時,在線程函數內部調用清理函數,強制線程函數退出。 這意味着兩件事:

  1. 當線程被取消時,它仍然會調用在線程函數內創建的所有C ++對象的析構函數。
  2. 我可以傳遞給在線程函數中創建的對象的清理函數指針。

我是對的,下面的代碼工作得很好嗎?


在下面的代碼中還有一個問題,當在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM