c++ - 我想杀死一个 std::thread 使用它的线程对象?

标签 c++ multithreading c++11 std stdthread

Possible Duplicate:
C++0x thread interruption

我正在尝试通过使用其线程对象来杀死/停止 c++ std::thread。

我们怎样才能做到这一点?

最佳答案

@bamboon 的回答很好,但我觉得这值得更强有力的声明。

无论您使用哪种语言,您的程序都会获取和释放资源:内存、文件描述符……对于一次性触发的简单程序,泄漏资源无关紧要:当程序结束时,现代操作系统会自动占用资源返回;但是对于长时间运行的程序,基本要求是不泄露资源,或者至少不重复。

因此,您应该从一开始就被教导,当您获得资源时,您必须确保它在某一时刻被释放:

void foo(int i) {
    int* array = malloc(sizeof(int) * i);

    /* do something */

    free(array);
}

所以,问自己这个问题:

  • 当我终止程序时会发生什么?
  • 当我终止线程时会发生什么?

好吧,正如我们所说,当程序结束时,操作系统会收集资源,因此假设(这是一些假设)您没有在 另一个 系统上获取资源或该系统受到很好的保护,免受此类虐待,没有伤害,没有犯规。

但是,当你杀死一个线程时,程序仍然运行,因此操作系统不会收集资源。您泄漏了内存,您锁定了一个无法再解锁的写入文件,... 您不应杀死线程

高级语言有办法处理这个问题:异常。因为程序无论如何都应该是异常安全的,Java(例如)将通过暂停线程来终止线程,在执行点抛出异常,然后轻轻展开堆栈。然而,C++ 中还没有这样的工具。

不可能吗?不,显然不是。实际上,您可以完美地重用相同的想法:

  • 封装std::threadinterruptible_thread类也会包含一个中断标志
  • 在启动时将标志的地址传递给std::thread,并以线程本地方式存储
  • 使用检查点来检查您的代码,检查中断标志是否已设置,以及何时引发异常

即:

// Synopsis
class interrupt_thread_exception;
class interruptible_thread;
void check_for_interrupt();

// Interrupt exception
class interrupt_thread_exception: public virtual std::exception {
public:
    virtual char const* what() const override { return "interrupt"; }
}; // class interrupt_thread_exception

// Interruptible thread
class interruptible_thread {
public:
    friend void check_for_interrupt();

    template <typename Function, typename... Args>
    interruptible_thread(Function&& fun, Args&&... args):
        _thread([](std::atomic_bool& f, Function&& fun, Args&&... args) {
                    _flag_ref = &f; fun(std::forward<Args>(args)...);
                },
                _flag,
                std::forward<Function>(fun),
                std::forward<Args>(args)...)
    {}

    bool stopping() const { return _flag.load(); }

    void stop() { _flag.store(true); }

private:
    static thread_local std::atomic_bool* _flag_ref = nullptr;

    std::atomic_bool _flag = false;
    std::thread _thread;
}; // class interruptible_thread

// Interruption checker
inline void check_for_interrupt() noexcept(false) {
    if (not interruptible_thread::_flag_ref) { return; }
    if (not interruptible_thread::_flag_ref->load()) { return; }

    throw interrupt_thread_exception();
} // check_for_interrupt

现在您可以在线程代码中添加适当的中断检查。

关于c++ - 我想杀死一个 std::thread 使用它的线程对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13893060/

相关文章:

c++ - 十进制 GCC 库

GUI 环境中的 C# 多线程

c++ - 基类与模板与生成的代码与宏的代码

c++ - NDEBUG 预处理器宏用于(在不同平台上)是什么?

java - Java wait(), notify() 的实现与锁有很大不同吗?

c++11 - std::shared_ptr 深拷贝对象

c++ - 为什么 uintptr_t 和 intptr_t 在 C(和 C++)标准中是可选类型?

c++ - 从只允许访问带索引的 vector 的对象创建 vector 包装器

c++ - 在 C++ 中打开并写入现有的 fstream 而无需覆盖/清除

Python: 'PyQt5.QtCore.pyqtSignal' 对象没有属性 'connect'