nnpp处理,线程

一个等待外部notify他的线程池

cpp 复制代码
class thread_pool_PDAC
{
  private:
    enum class worker_state
    {
        Idle,
        TryFetch,
        Work
    };

    enum class cu_state
    {
        Pending,
        Ready,
        Running
    };

    static const int MaxThreads = 16;

    std::atomic_bool _is_running;
    std::mutex _mutex;
    std::condition_variable _cond;
    std::condition_variable _finishedCond;
    size_t _thread_no;
    std::vector<std::thread> _threads;

    std::function<void(int, int)> _workTask;
    std::function<bool(int)> _checkTask;

    bool _needCheck = false;
    std::deque<int> _pendingCUs;
    std::queue<int> _readyCUs;
    std::unordered_map<int, cu_state> _cuStates;
    std::atomic<int> activeNum{0};

  public:
    thread_pool_PDAC(const thread_pool_PDAC &tp) = delete;
    thread_pool_PDAC &operator=(const thread_pool_PDAC &tp) = delete;

  public:
    thread_pool_PDAC(size_t no = 1) : _is_running(false), _thread_no(no)
    {
        if (_thread_no >= MaxThreads)
        {
            _thread_no = MaxThreads;
        }
        _workTask = [](int, int) {};
        _checkTask = [](int) { return true; };
    }

    ~thread_pool_PDAC()
    {
        if (_is_running)
        {
            stop();
        }
    }

  private:
    bool tryTakeReadyTaskLocked(int &cuIndex)
    {
        while (!_readyCUs.empty())
        {
            int candidate = _readyCUs.front();
            _readyCUs.pop();

            auto iter = _cuStates.find(candidate);
            if (iter == _cuStates.end() || iter->second != cu_state::Ready)
            {
                continue;
            }

            iter->second = cu_state::Running;
            cuIndex = candidate;

            if (!_readyCUs.empty())
            {
                _cond.notify_one();
            }
            return true;
        }

        return false;
    }

    bool tryTakePendingCandidateLocked(int &cuIndex)
    {
        while (!_pendingCUs.empty())
        {
            int candidate = _pendingCUs.front();
            _pendingCUs.pop_front();

            auto iter = _cuStates.find(candidate);
            if (iter == _cuStates.end() || iter->second != cu_state::Pending)
            {
                continue;
            }

            cuIndex = candidate;
            return true;
        }

        _needCheck = false;
        return false;
    }

    bool tryFetchReadyTask(int &cuIndex)
    {
        std::lock_guard<std::mutex> lock(_mutex);
        return tryTakeReadyTaskLocked(cuIndex);
    }

    bool tryTakePendingCandidate(int &cuIndex)
    {
        std::lock_guard<std::mutex> lock(_mutex);
        return tryTakePendingCandidateLocked(cuIndex);
    }

    bool promoteCheckedCandidate(int cuIndex)
    {
        std::lock_guard<std::mutex> lock(_mutex);
        auto iter = _cuStates.find(cuIndex);
        if (iter == _cuStates.end())
        {
            return false;
        }

        if (iter->second != cu_state::Pending)
        {
            return false;
        }

        iter->second = cu_state::Running;
        return true;
    }

    void restorePendingCandidate(int cuIndex)
    {
        std::lock_guard<std::mutex> lock(_mutex);
        auto iter = _cuStates.find(cuIndex);
        if (iter == _cuStates.end() || iter->second != cu_state::Pending)
        {
            return;
        }

        _pendingCUs.push_back(cuIndex);
        _needCheck = false;
    }

    void finishTask(int cuIndex)
    {
        std::lock_guard<std::mutex> lock(_mutex);
        auto iter = _cuStates.find(cuIndex);
        if (iter != _cuStates.end() && iter->second == cu_state::Running)
        {
            _cuStates.erase(iter);
        }

        _finishedCond.notify_all();
        if (!_readyCUs.empty())
        {
            _cond.notify_one();
        }
    }

    void work(int threadIndex)
    {
        worker_state state = worker_state::Idle;
        int cuIndex = -1;

        while (_is_running)
        {
            switch (state)
            {
            case worker_state::Idle: {
                std::unique_lock<std::mutex> lock(_mutex);
                _cond.wait(lock, [this]() { return !_is_running || !_readyCUs.empty() || _needCheck; });
                if (!_is_running)
                {
                    return;
                }
                state = worker_state::TryFetch;
                break;
            }
            case worker_state::TryFetch: {
                if (tryFetchReadyTask(cuIndex))
                {
                    state = worker_state::Work;
                    break;
                }

                if (!tryTakePendingCandidate(cuIndex))
                {
                    state = worker_state::Idle;
                    break;
                }

                bool isReady = _checkTask ? _checkTask(cuIndex) : false;
                if (isReady && promoteCheckedCandidate(cuIndex))
                {
                    state = worker_state::Work;
                    break;
                }

                restorePendingCandidate(cuIndex);
                cuIndex = -1;
                state = worker_state::Idle;
                break;
            }
            case worker_state::Work: {
                ++activeNum;
                _workTask(threadIndex, cuIndex);
                --activeNum;
                finishTask(cuIndex);
                cuIndex = -1;
                state = worker_state::TryFetch;
                break;
            }
            }
        }
    }

  public:
    void setThreadNumber(size_t no)
    {
        if (no >= MaxThreads)
        {
            no = MaxThreads;
        }
        this->_thread_no = no;
    }

    void start()
    {
        this->_is_running = true;
        {
            std::lock_guard<std::mutex> lock(_mutex);
            _needCheck = !_pendingCUs.empty();
        }

        for (size_t i = 0; i < _thread_no; i++)
        {
            _threads.emplace_back(std::thread(&thread_pool_PDAC::work, this, static_cast<int>(i)));
        }

        _cond.notify_all();
    }

    void stop()
    {
        {
            std::lock_guard<std::mutex> lock(_mutex);
            _is_running = false;
            _needCheck = false;
        }
        _cond.notify_all();

        for (std::thread &thd : _threads)
        {
            if (thd.joinable())
            {
                thd.join();
            }
        }
        _threads.clear();
    }

    void setWorkTask(const std::function<void(int, int)> &t) { this->_workTask = t; }

    void setFetchTask(const std::function<bool(int)> &t) { this->_checkTask = t; }

    void EnqueueTask(int cuIndex)
    {
        if (!_is_running)
        {
            return;
        }

        std::lock_guard<std::mutex> lock(_mutex);
        auto inserted = _cuStates.emplace(cuIndex, cu_state::Pending);
        if (!inserted.second)
        {
            return;
        }

        _pendingCUs.push_back(cuIndex);
        _needCheck = true;
        _cond.notify_one();
        _finishedCond.notify_all();
    }

    void notify(int cuIndex)
    {
        if (!_is_running)
        {
            return;
        }

        std::lock_guard<std::mutex> lock(_mutex);
        auto iter = _cuStates.find(cuIndex);
        if (iter == _cuStates.end())
        {
            // 外界 CU,错误
            std::cerr << "[Error]: unregistered CU: " << cuIndex << std::endl;  
            return;
        }

        if (iter->second == cu_state::Pending)
        {
            iter->second = cu_state::Ready;
            _readyCUs.push(cuIndex);
            _cond.notify_one();
        }
    }

    void waitFinished()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _finishedCond.wait(lock, [this]() { return _cuStates.empty() && activeNum.load(std::memory_order_acquire) == 0; });
    }
};
相关推荐
hetao17338376 分钟前
2026-09-01~09-04 hetao1733837 的刷题记录
c++·算法
Evand J24 分钟前
【MATLAB例程,图像滤波5】 反谐波均值滑动窗口滤波(CHMF)图像降噪与质量评价,附代码下载链接
图像处理·算法·计算机视觉·matlab·均值算法·滑动窗口滤波·均值滑动
血小板要健康1 小时前
链表 阶段算法总结
java·数据结构·笔记·算法·leetcode·链表
a187927218311 小时前
【算法】回溯算法(三):三记重锤与 N 皇后——记忆化、状态设计与三层漏斗
算法·leetcode·go·剪枝·回溯·n皇后·算法讲解
HugoStudio_SWAN3 小时前
洛谷 P1420 / P1179 / B4262 最长连号、数字统计与词频统计——统计的三种面孔
c++·学习·程序人生·算法
青 春 记 忆4 小时前
LeetCode 350. 两个数组的交集 II|Python 解法详解
python·算法·leetcode
raindayinrain4 小时前
c++并发
c++
j7~4 小时前
【C++】智能指针的使用及其原理--详解
c++·c++11·内存泄漏·智能指针·raii·boost智能指针
阳明山水4 小时前
销量预测2025—2026:从模型竞赛到系统融合的范式转型
人工智能·深度学习·算法·机器学习·架构
桐盛科技5 小时前
拒绝“漂绿”风险:基于边缘计算的碳排放数据清洗算法与实时校验逻辑
人工智能·算法·边缘计算