首页 > 解决方案 > 在主线程中工作时暂停后台线程?

问题描述

我有一个 GUI 读取/写入一些包含许多条目的数据,其中写入单个条目很快,但写入所有条目需要很长时间。

据我所知,我有一个正在运行和工作的解决方案,但这是我的第一个并发 C++ 代码,也许“它有效”并不是衡量正确性的最佳指标。

为了简化代码:

这是简化的代码:

// includes ..
using namespace std; // only to make the question less verbose
class Gui {
    vector<int> data;

    mutex data_mtx;
    condition_variable data_cv;
    atomic_bool background_blocked = false;
  
    // ...
}

Gui::Gui() {
    // some init work .. like obtaining the raw data
    thread background_worker([this]{fill_data();});
    background_worker.detach();
}

void Gui::fill_data() { // should only do processing work while main thread does not
    unique_lock data_lock(data_mtx);
    background_blocked = false;
    for(auto& entry : raw_data) {
        data_cv.wait(data_lock, [this]{return !background_blocked;});
        if(!is_processed(entry)) proccess(entry);
    }
}

int Gui::get_single_entry(int i) { // called by main thread - should respond immediately / pause background work
    background_blocked = true;
    unique_lock data_lock(data_mtx);

    auto& entry = data[i];
    if(!is_processed(entry)) process(entry);
    const auto result = entry;

    background_blocked = false;
    data_lock.unlock();
    data_cv.notify_one();

    return result;
}

// ...

(一个无用但说明性的示例可能是data仅包含偶数的原始示例,process(..)添加1到该数字,is_processed(..)如果该数字是奇数则返回 true。只有在处理完所有内容后才能知道的属性可能是已处理数据中的素数 -例如process(..)也可以增加一个素数计数器)

我想我主要不确定安全阅读。我现在找不到它,但是 gcc(我使用的)文档说“如果没有线程正在写入变量,则从任何线程读取变量都是安全的” - 我没有看到它说任何关于只有 1 个线程在写入,但其他线程同时在读取的情况。在后一种情况下,我假设不仅可能存在竞争条件,而且写入也可能是半完成的,因此读取可能会导致垃圾?

标签: c++multithreadingmutexcondition-variable

解决方案


推荐阅读