终止工作线程的正确方法

4

嗨,我正在尝试找到最佳的和平方式来终止工作线程。我有以下代码:

class test{
  public:
test() {}
~test() {}

std::atomic<bool> worker_done;


int a;
void pr() {
    while (true) {
        if (worker_done) {
            break;
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        printf("%d \n", a++);
    }
}

std::thread* m_acqThread;
void continuous() {
    m_acqThread = new std::thread(&test::pr, this);
}

void stopThread(){
    if (m_acqThread) {
        if (m_acqThread->joinable())
            m_acqThread->join();
        delete m_acqThread;
        m_acqThread = nullptr;
    }
}


};


int main(){

test t;
t.continuous();

std::this_thread::sleep_for(std::chrono::milliseconds(2000));
t.worker_done = true;

t.stopThread();


std::string str;
std::cin.clear();
getline(std::cin, str);
return 0;

除了将"worker_done"设置为true之外,还有更好的通知工作线程终止的方法吗?

谢谢


“最好的和平方式…” 有暴力的方式吗? - Devin L.
请使用unique_ptr代替手动指针跟踪。 - GManNickG
1
非敌对性杀死是我认为他/她所指的术语。 - apollosoftware.org
std::thread 没有这样的接口。要么使用粗暴的方法,要么使用标志。 - Baum mit Augen
1
不,工作线程需要知道您希望它结束。因此必须发送一个信号。 - Galik
顺便提一下,您不需要为线程使用指针,只需将其用作值对象即可。 - Galik
1个回答

2
你现有的代码已经很好了:如果你在程序开启时启动一个线程,在程序关闭时需要停止它,使用 atomic<bool> 是正确的方法。
也可以像这样使用std::atomic_flag
#include <thread>
#include <atomic>
#include <iostream>

std::atomic_flag lock;
int n = 0;

void t()
{
    while (lock.test_and_set())
    {
        ++n;
        std::this_thread::sleep_for(std::chrono::milliseconds(250));
    }
}

int main()
{
    lock.test_and_set();
    std::thread t(&t);
    std::this_thread::sleep_for(std::chrono::seconds(2));
    lock.clear();
    t.join();
    std::cout << n << std::endl;
    std::cin.get();
}

你可以阅读关于为什么你可能希望选择atomic_flag而不是atomic<bool>,但个人而言,我更喜欢像这样使用atomic<bool>,因为它更易读:
std::atomic<bool> runThread;
int n = 0;

void t()
{
    while (runThread)
    {
        ++n;
        std::this_thread::sleep_for(std::chrono::milliseconds(250));
    }
}

int main()
{
    runThread = true;
    std::thread t(&t);
    std::this_thread::sleep_for(std::chrono::seconds(2));
    runThread = false;
    t.join();
    std::cout << n << std::endl;
    std::cin.get();
}

原子标志会更好吗? - zzxyz
至少 atomic<bool> 更便宜。 - LWimsey
2
原子标记听起来像一个被遗忘的50年代超级英雄。 - user4581301
1
atomic_flag 没有测试操作,只有 test_and_setclear。使用这些原语向另一个线程发出信号是不必要的困难。唯一的优点是它被标准定义为无锁而不是实现定义。但是,在所有主要的实现中,atomic<bool> 都是无锁的。(没有注意到 Tas 已经讨论了 atomic_flag。) - Arne Vogel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接