You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程workerClass数据独立存储及跨类全局vector检索需求

多线程核心独立数据存储实现方案

首先得明确你的核心诉求:每个线程对应一个CPU核心,各自维护独立的id、packetCount和packetDropped属性,通过全局的std::vector<workerClass>来统一存储这些实例,方便后续在其他类中检索数据。下面是具体的实现思路和代码示例:

1. 调整workerClass类结构

首先要把run函数设为public(线程需要调用它),同时确保原子变量的初始化逻辑清晰:

#include <atomic>
#include <vector>
#include <thread>
#include <iostream>
#include <chrono>

class workerClass {
private:
    std::atomic<int> id;
    std::atomic<int> packetCount;
    std::atomic<int> packetDropped;
    // 可选:添加停止标志,优雅终止线程
    std::atomic<bool> stopFlag{false};
public:
    // 构造函数初始化原子变量
    workerClass() : id(-1), packetCount(0), packetDropped(0) {}

    // 线程执行的核心函数
    void run(int threadId) {
        id.store(threadId, std::memory_order_relaxed);
        // 这里模拟线程的业务逻辑:处理数据包,更新计数
        while (!stopFlag.load(std::memory_order_relaxed)) {
            // 示例:每处理10个数据包模拟丢1个
            packetCount.fetch_add(1, std::memory_order_relaxed);
            if (packetCount.load(std::memory_order_relaxed) % 10 == 0) {
                packetDropped.fetch_add(1, std::memory_order_relaxed);
            }
            // 实际业务中替换为真实数据包处理逻辑
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
    }

    // 优雅停止线程的接口
    void stop() {
        stopFlag.store(true, std::memory_order_relaxed);
    }

    // 提供获取数据的接口,供其他类检索
    int getId() const { return id.load(std::memory_order_relaxed); }
    int getPacketCount() const { return packetCount.load(std::memory_order_relaxed); }
    int getPacketDropped() const { return packetDropped.load(std::memory_order_relaxed); }
};

2. 全局vector的初始化与线程创建

全局vector需要在程序启动时根据CPU核心数初始化,然后为每个核心创建对应的线程:

// 全局存储每个核心对应的worker实例
std::vector<workerClass> workers;
// 存储线程对象,方便管理与回收
std::vector<std::thread> threads;

void initWorkers() {
    // 获取当前系统的CPU核心数
    size_t coreCount = std::thread::hardware_concurrency();
    if (coreCount == 0) {
        coreCount = 4; //  fallback值,防止获取核心数失败
    }
    workers.resize(coreCount);

    // 为每个核心创建线程,绑定对应的worker的run函数
    for (size_t i = 0; i < coreCount; ++i) {
        threads.emplace_back(&workerClass::run, &workers[i], static_cast<int>(i));
    }
}

// 程序退出时回收线程资源
void cleanupWorkers() {
    // 先通知所有线程停止
    for (auto& worker : workers) {
        worker.stop();
    }
    // 等待所有线程执行完毕
    for (auto& thread : threads) {
        if (thread.joinable()) {
            thread.join();
        }
    }
}

3. 在其他类中检索数据

后续可以在任意类中直接访问全局的workers vector,通过索引或者遍历获取每个核心的统计数据:

class DataRetriever {
public:
    void printWorkerStats() {
        std::cout << "=== 各核心线程统计数据 ===" << std::endl;
        for (const auto& worker : workers) {
            std::cout << "核心ID: " << worker.getId() 
                      << " | 处理数据包总数: " << worker.getPacketCount() 
                      << " | 丢包数: " << worker.getPacketDropped() << std::endl;
        }
    }
};

4. 关键注意事项

  • 原子变量内存序:这里用std::memory_order_relaxed足够,因为我们只需要保证变量读写的原子性,不需要严格的内存同步。
  • 线程安全:如果只是检索数据(只读操作),无需额外加锁;如果有修改worker实例的操作,需要配合std::mutex保证线程安全。
  • 资源回收:一定要在程序退出时调用cleanupWorkers(),避免线程资源泄漏。

内容的提问来源于stack exchange,提问作者Vinay Shukla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:07:05