繁体   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