摔死我们我好好

为了判断是否完成了队列中数据的写入操作,可以引入一个标志位或计数器,结合条件变量(std::condition_variable)来实现线程间的同步机制,确保写入操作完成后可以通知主线程或其他逻辑。


改进设计:增加写入完成判断

核心逻辑
  1. 标志位

    • 使用 std::atomic<bool> 标志当前是否有写入操作正在进行。
    • 在写入完成时,将标志位设置为 false
  2. 条件变量

    • 在写入操作完成后,通过条件变量通知等待线程。

实现代码

1. 修改 QueueProcessor
#include "SharedQueue.h"
#include "DatabaseWriter.h"
#include <atomic>
#include <condition_variable>
#include <thread>
#include <vector>

extern SharedQueue<DataModelA> queueA;

class QueueProcessor {
public:
    QueueProcessor() : isFlushing(false) {}

    void start() {
        workerThread = std::thread(&QueueProcessor::processQueue, this);
    }

    void stop() {
        stopFlag.store(true);
        if (workerThread.joinable()) workerThread.join();
    }

    void flushQueueToDatabase() {
        {
            std::lock_guard<std::mutex> lock(mtx);
            if (isFlushing.load()) {
                std::cout << "Flush already in progress...\n";
                return;
            }
            isFlushing.store(true);
        }

        // 启动异步写入线程
        std::thread([this]() {
            DatabaseWriter dbWriter;
            std::vector<DataModelA> dataBatch;

            // 从队列中提取所有数据
            queueA.popAll(dataBatch);
            if (!dataBatch.empty()) {
                dbWriter.writeBatchA(dataBatch);
            }

            // 写入完成,更新标志位并通知主线程
            {
                std::lock_guard<std::mutex> lock(mtx);
                isFlushing.store(false);
                cv.notify_all();
            }
        }).detach();
    }

    // 等待写入完成
    void waitUntilFlushed() {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [this]() { return !isFlushing.load(); });
        std::cout << "Flush operation completed.\n";
    }

private:
    std::atomic<bool> stopFlag = false; // 停止标志
    std::atomic<bool> isFlushing;      // 写入中标志
    std::thread workerThread;          // 工作线程
    std::mutex mtx;                    // 用于保护标志位
    std::condition_variable cv;        // 条件变量

    void processQueue() {
        while (!stopFlag.load()) {
            std::this_thread::sleep_for(std::chrono::milliseconds(500));
            // 可以监控队列或执行其他任务
        }
    }
};

2. 主程序调用示例
#include <thread>
#include <chrono>
#include <iostream>

void produceDataA();

int main() {
    SharedQueue<DataModelA> queueA;
    QueueProcessor processor;

    // 启动生产者线程
    std::thread producerThread(produceDataA);

    // 启动队列处理器
    processor.start();

    // 模拟写入操作
    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "Flushing data to database...\n";
    processor.flushQueueToDatabase();

    // 等待写入完成
    processor.waitUntilFlushed();

    // 停止处理器
    processor.stop();
    producerThread.join();

    return 0;
}

功能解释

  1. 写入判断

    • isFlushing 标志位表示当前是否在写入。
    • 主线程通过 waitUntilFlushed 等待写入完成。
  2. 非阻塞触发

    • flushQueueToDatabase 触发写入后立即返回,写入操作由独立线程完成。
  3. 等待写入完成

    • 使用 cv.wait 阻塞当前线程,直到写入完成后被通知。
  4. 线程安全

    • std::mutex 确保多个线程对 isFlushing 标志位的访问安全。

输出示例

Flushing data to database...
Writing DataModelA to database: id=1, value="test1"
Writing DataModelA to database: id=2, value="test2"
Flush operation completed.

设计优点

  1. 可控性强:主线程可以明确知道写入何时完成,方便后续操作。
  2. 安全性高:基于条件变量实现线程间同步,避免不必要的忙等待。
  3. 灵活性:支持多个触发点调用写入,同时保证每次写入操作独立完成。

这种实现适用于需要实时监控写入状态的场景,比如确保写入操作完成后再进行后续逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值