简体   繁体   English

C++ 杀死一个 std::thread

[英]C++ Killing a std::thread

I have a program that creates a thread that listens for an event.我有一个程序可以创建一个监听事件的线程。 There is a situation in which this thread will never receive this event, and I must terminate it.有一种情况,这个线程永远不会收到这个事件,我必须终止它。 I know how to catch the case in which it will not receive this event.我知道如何捕捉它不会收到此事件的情况。

I've created a std::thread , however I found nothing on how to terminate the thread.我创建了一个std::thread ,但是我没有发现有关如何终止线程的任何信息。 I've tried calling我试过打电话

t.detach()

And then letting the destructor so the work, but I cannot clean up resources allocated by the thread this way.然后让析构函数工作,但我无法以这种方式清理线程分配的资源。

My questions are: 1. Is there a way to send a SIGKILL or equivalent to a std::thread to kill it?我的问题是: 1. 有没有办法发送 SIGKILL 或等效于std::thread来杀死它? And 2. Is there a way to catch this signal from within the thread to clean up resources?和 2. 有没有办法从线程内捕获这个信号来清理资源?

The question asked (and answered) How do I terminate a thread in C++11?提出(并回答)的问题如何在 C++11 中终止线程? doesn't answer my question as I want to terminate the thread from it's parent, not from within the thread.没有回答我的问题,因为我想从它的父线程而不是从线程内终止线程。

Furthermore, my problem is that my worker thread can be either waiting for a blocking system call (ie, an incoming packet) or a conditional variable, which is why this is tricky.此外,我的问题是我的工作线程可能正在等待阻塞系统调用(即传入数据包)或条件变量,这就是为什么这很棘手。

Generally killing thread is the undesired behaviour, you want to initiate the thread , do the necessary implementation based on the condition, and if the condition don't satisfy then you could exit it cleanly.通常杀死线程是不受欢迎的行为,你想启动线程,根据条件做必要的实现,如果条件不满足那么你可以干净地退出它。 Probably use std::condition_variable ... and set the condition from main thread so that child could exit based on certain condition.可能使用 std::condition_variable ... 并从主线程设置条件,以便孩子可以根据特定条件退出。

You can't kill a thread by standard c++ ways and, generally speaking, it's not a desirable behavior.您不能通过标准的 C++ 方式杀死线程,一般来说,这不是一种理想的行为。 You can use conditional variables to achieve a similar behavior with a "signal system":您可以使用条件变量通过“信号系统”实现类似的行为:

#include <mutex>
#include <thread>
#include <atomic>
#include <iostream>

std::mutex m;
std::condition_variable cv;
std::atomic_bool state;

void worker_thread() {
    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk, [] { //waits for the notify_one "signal"
        return state.load(); //returns false if the waiting should be continued. 
    });
    std::cout << "Finished waiting..." << std::endl;
}

int main() {
    state.store(false); //set initial state
    std::thread worker(worker_thread);

    std::cout << "Start waiting..." << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(2)); //do some work here
    {
        std::lock_guard<std::mutex> lk(m); //avoids cv to get notified before been in wait state
        state.store(true);
        cv.notify_one(); //emit the signal once "state" var is true
    }

    worker.join();
    return 0;
}
  1. Is there a way to send a SIGKILL or equivalent to a std::thread to kill it?有没有办法发送 SIGKILL 或等效于 std::thread 来杀死它?

There is no such equivalent;没有这样的等价物; at least a standard one.至少是标准的。

  1. Is there a way to catch this signal from within the thread to clean up resources?有没有办法从线程内捕获这个信号来清理资源?

There is no standard way in C++ to signal a thread. C++ 中没有标准的方法来向线程发出信号。

POSIX has pthread_kill that can be used to signal a thread. POSIX 具有pthread_kill可用于向线程发出信号。 Note that "stop", "continue", or "terminate" signals affect the entire process, so this is not for what you're asking exactly.请注意,“停止”、“继续”或“终止”信号会影响整个过程,因此这不是您要问的确切内容。

However, asynchronous signal handlers are limited on what they can do, and resource cleanup won't be possible.但是,异步信号处理程序的功能受到限制,并且无法进行资源清理。 What you should do is let the thread know that it should terminate, and let it stop and cleanup voluntarily.你应该做的是让线程知道它应该终止,让它自动停止和清理。

thread that listens for an event.监听事件的线程。

Solution depends on what kind of listening we are considering.解决方案取决于我们正在考虑的聆听类型。 If it is a condition variable, you can set an atomic boolean to request termination and wake up the thread by notifying.如果是条件变量,你可以设置一个原子布尔值来请求终止并通过通知来唤醒线程。

If listening is a blocking system call, solution is a bit trickier.如果侦听是阻塞系统调用,则解决方案有点棘手。 The great thing about raising a signal, is that it interrupts blocking system calls.发出信号的好处在于它会中断阻塞的系统调用。 You can use the handler to set a volatile sig_atomic_t variable that the thread can read and voluntarily return.您可以使用处理程序设置线程可以读取并自愿返回的volatile sig_atomic_t变量。 The interruption may give your thread a chance to check the variable before resuming the wait.中断可能会让您的线程有机会在恢复等待之前检查变量。 The caveat is that we must turn that may into a guarantee:需要说明的是,我们必须把可能变成一个保证:

You must register the signal handler using sigaction (standard POSIX function; not standard C++) with SA_RESTART unset.您必须使用未设置SA_RESTART sigaction (标准 POSIX 函数;不是标准 C++)注册信号处理程序。 Otherwise depending on system defaults, the system call might resume instead of returning.否则取决于系统默认值,系统调用可能会恢复而不是返回。


Another approach is to send the event that the other thread is waiting for.另一种方法是发送另一个线程正在等待的事件。 This may be simpler or trickier than above depending on what kind of event we are considering.这可能比上面更简单或更棘手,具体取决于我们正在考虑的事件类型。 For example, when listening on a socket, it is typically possible to connect to that socket.例如,在侦听套接字时,通常可以连接到该套接字。


There is a proposal to introduce std::jthread thread wrapper into a future C++ standard, which offers a portable way to request a thread to stop.有一个提议std::jthread线程包装器引入未来的 C++ 标准,它提供了一种可移植的方式来请求线程停止。 Unfortunately, I don't know what guarantees there would be regarding blocking system calls.不幸的是,我不知道关于阻塞系统调用会有什么保证。

There's no standard way to kill off a thread, but depends on the platform.没有终止线程的标准方法,但取决于平台。

On windows, you may use TerminateThread for example.例如,在 Windows 上,您可以使用TerminateThread

However, be advised, unless you know of the sides-effects, etc., this is often-times an anti-pattern to do so.但是,请注意,除非您知道副作用等,否则这通常是一种反模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM