告诉std ::线程在满足条件时杀死/停止自身 [英] Telling an std::thread to kill/stop itself when a condition is met

查看:3232
本文介绍了告诉std ::线程在满足条件时杀死/停止自身的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个工作线程 tWorker ,当 Boss code> work(),直到 bRetired 为true。 std :: mutex mtx ,锁定一些数据( vFiles ),以便 tWorker 在他处理时拥有它。



如何使 tWorker commit suicide一次 bRetired 成为 true ?当线程停止执行时, mutex 如何被销毁?



我读过 std :: thread 对象不能以任何方式中断。让线程什么也不做(或调用 std :: this_thread :: yield())提供了与截断线程相同的效果?

  class Boss {
private:
std :: thread tWorker;
std :: mutex mtx;
bool bRetired;
std :: vector< std :: string> vFiles;

void work(){
while(bRetired == false){
//做你的工作!
mtx.lock();
// ...做一些关于vFiles ...
mtx.unlock();
}

// tWorker已退休,自杀
// **如何? **

//这是否足够,如果我想杀死线程?
std :: this_thread :: yield();
}

public:
Boss(){
bRetired = false;
tWorker = std :: thread(& Boss :: work,this);

//工人独立完成其工作
// **奖金问题**:这应该是tWorker.join()还是tWorker.detach()?
tWorker.detach();
}

retire(){
bRetired = true;
}
}

注意 >


  • 工作线程退出后无法重新启动。

  • 工作线程在后台工作,中断主线程的执行。


解决方案

std :: thread :: yield() 不需要,不会杀死调用线程:


提供一个提示,以重新安排线程的执行,允许其他线程运行。 p>

只需退出该函数即可退出线程。



bRetired 不正确,因为两个线程可以访问同一个内存位置,其中一个线程正在修改它:这是未定义的行为。此外,执行 run()的线程不会看到函数 retire() $ c>:use atomic< bool> 原子性和可见性。



如果 join() ,构造函数不会返回,直到线程退出,不可能调用 retire(),因为对象将不可用(因为构造函数不会返回)。如果需要与退出的线程同步,那么在 detach() join() retire() function:

  b bRetired = true; 
tWorker.join();
}

使用RAII获取 mutex es( std :: lock_guard ),以确保它总是释放。 mutex 在超出范围时将被销毁,在这种情况下,其包含的类会被销毁。


Say I have a worker thread tWorker, which is initialized when Boss is constructed and tells it to do work(), until bRetired is true. An std::mutex, mtx, locks some data (vFiles) so that tWorker owns it when he's working on it.

How do I make tWorker "commit suicide" once bRetired becomes true? How would the mutex be destroyed when the thread stops execution?

I've read that std::thread objects cannot be interrupted in any way. Does letting the thread do nothing (or calling std::this_thread::yield()) provide the same effect as killing the thread?

class Boss {
private:
    std::thread tWorker;
    std::mutex mtx;
    bool bRetired;
    std::vector< std::string > vFiles;

    void work() {
        while ( bRetired == false ) {
            // Do your job!
            mtx.lock();
            // ... Do something about vFiles ...
            mtx.unlock();
        }

        // tWorker has retired, commit suicide
        // ** How? **

        // Does this suffice if I want to "kill" the thread?
        std::this_thread::yield(); 
    }

public:
    Boss() {
        bRetired = false;
        tWorker = std::thread( &Boss::work, this );

        // Have worker do its job independently
        // **Bonus Question** : Should this be tWorker.join() or tWorker.detach()?
        tWorker.detach();
    }

    retire() {
        bRetired = true;
    }
}

Notes

  • The worker thread cannot be started again once it is retired.
  • The worker thread works on the background without interrupting the main thread's execution.

解决方案

The call to std::thread::yield() is unrequired and does not kill the calling thread:

Provides a hint to the implementation to reschedule the execution of threads, allowing other threads to run.

Just exit the function to exit the thread.

Note that the use of bRetired is incorrect as two threads can be accessing the same memory location and one of those threads is modifying it: this is undefined behaviour. Also, the change made in the function retire(), a different thread, will not be seen by the thread executing run(): use atomic<bool> for atomicity and visibility.

If join() was used within the constructor the constructor would not return until the thread exited, which would never happen as it would be impossible to call retire() because the object would not be available (as the constructor would not have returned). If it is required to synchronize with the exiting of the thread then do not detach() but join() in the retire() function:

void retire() {
    bRetired = true;
    tWorker.join();
}

Use RAII for acquiring mutexes (std::lock_guard for example) to ensure it always released. The mutex will be destroyed when it goes out of scope, in this case when its containing class is destructed.

这篇关于告诉std ::线程在满足条件时杀死/停止自身的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆