C++ 我想使用其线程对象杀死 std::thread 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13893060/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:48:14  来源:igfitidea点击:

I want to kill a std::thread using its thread object?

c++multithreadingc++11stdstdthread

提问by CPS

Possible Duplicate:
C++0x thread interruption

可能的重复:
C++0x 线程中断

I am trying to kill/stop a c++ std::thread by using its thread object.

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

How can we do this?

我们应该怎么做?

回答by Matthieu M.

@bamboon's answer is good, however I feel this deserves a stronger statement.

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

Whatever the language you use, your program will acquire and release resources: memory, file descriptors, ... For simple programs that are fired in one shots, leaking resources does not matter much: when the program ends modern OSes automatically take the resources back; however for long-running programs a basic requirement is not to leak resources, or at least not repetitively.

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

Therefore, you should have been taught from the beginning that when you acquire a resource you will have to ensure it is released at one point:

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

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

    /* do something */

    free(array);
}

So, ask yourself the question:

所以,问自己一个问题:

  • what happens when I kill the program ?
  • what happens when I kill the thread ?
  • 当我杀死程序时会发生什么?
  • 当我杀死线程时会发生什么?

Well, as we said, when a program ends the OS gathers the resources back, so assuming (and this is some assumption) that you did not acquire a resource on anothersystem OR that this system is well protected against such abuse, no harm, no foul.

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

However, when you kill a thread, the program still runs, thus the OS does not gather the resources back. You leaked memory, you locked a file for writing that you cannot unlock any longer, ... You shall not kill threads.

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

Higher level languages have a way to handle this: exceptions. Because programs should be exception safe anyway, Java (for example) will kill a thread by pausing it, throwing an exception at the point of execution, and gently unwind the stack. However there is no such facility in C++, yet.

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

Is it impossible ? No, obviously not. Actually, you could perfectly reuse the very same idea:

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

  • encapsulate std::thread, interruptible_threadclass will also contain an interrupt flag
  • pass the address of the flag to std::threadwhen launching it, and store it in a thread-local way
  • instrument your code with check-points where you check whether the interrupt flag is set or not, and when it is throw an exception
  • 封装std::threadinterruptible_thread类也将包含一个中断标志
  • std::thread启动时将标志的地址传递给,并以线程本地方式存储
  • 使用检查点检测您的代码,您可以在其中检查是否设置了中断标志,以及何时抛出异常

That is:

那是:

// 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

Now you can just sprinkle your threaded code with checks for interrupt at appropriate places.

现在你可以在你的线程代码中在适当的地方检查中断。

回答by Stephan Dollberg

You can't.

你不能。

std::threadsare not interruptible. You can use boost::threadwhich offers this feature.

std::threads不可中断。您可以使用boost::thread提供此功能的产品。

Boost does this by defining "interrupt points" on which the thread will end if it is interrupted and reaches such a point.

Boost 通过定义“中断点”来实现这一点,如果线程被中断并到达这样的点,则线程将在该点上结束。

Nevertheless, most of the time thinking about a redesign might be the cleanest and easiest way to reach what you are trying to achieve.

尽管如此,大多数时候考虑重新设计可能是达到您想要实现的目标的最简洁、最简单的方法。

If you are still looking for a C++11 implementation of interruptible threads checkout out Anthony Williams (owner of boost thread) book "C++ Concurrency in Action". He goes through a basic implementation of how such a thing can be achieved.

如果您仍在寻找可中断线程的 C++11 实现,请查看 Anthony Williams(boost thread 的所有者)一书“C++ Concurrency in Action”。他经历了如何实现这样的事情的基本实现。

std::thread::native_handlegives you access to the platform specific underlying thread handle which might support interrupting, however this approach makes your code unportable and probably not cleaner in any way.

std::thread::native_handle使您可以访问可能支持中断的特定于平台的底层线程句柄,但是这种方法使您的代码不可移植并且可能不会以任何方式更清晰。