c++11实现的线程池

基于C++11 functional函数封包+condition_variable条件变量实现的任务线程池

HThreadPool

#ifndef HW_THREAD_POOL_H_
#define HW_THREAD_POOL_H_

#include <vector>
#include <thread>
#include <queue>
#include <functional>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <future>
#include <memory>
#include <utility>

//#include "hlog.h"
#include "hthread.h"

class HThreadPool {
public:
    using Task = std::function<void()>;

    HThreadPool(int size = std::thread::hardware_concurrency())
        : pool_size(size), idle_num(size), status(STOP) {
    }

    ~HThreadPool() {
        stop();
    }

    int start() {
        if (status == STOP) {
            status = RUNNING;
            for (int i = 0; i < pool_size; ++i) {
                workers.emplace_back(std::thread([this]{
                    //hlogd("work thread[%X] running...", gettid());
                    while (status != STOP) {
                        while (status == PAUSE) {
                            std::this_thread::yield();
                        }

                        Task task;
                        {
                            std::unique_lock<std::mutex> locker(_mutex);
                            _cond.wait(locker, [this]{
                                return status == STOP || !tasks.empty();
                            });

                            if (status == STOP) return;

                            if (!tasks.empty()) {
                                --idle_num;
                                task = std::move(tasks.front());
                                tasks.pop();
                            }
                        }

                        task();
                        ++idle_num;
                    }
                }));
            }
        }
        return 0;
    }

    int stop() {
        if (status != STOP) {
            status = STOP;
            _cond.notify_all();
            for (auto& worker : workers) {
                worker.join();
            }
        }
        return 0;
    }

    int pause() {
        if (status == RUNNING) {
            status = PAUSE;
        }
        return 0;
    }

    int resume() {
        if (status == PAUSE) {
            status = RUNNING;
        }
        return 0;
    }

    int wait() {
        while (1) {
            if (status == STOP || (tasks.empty() && idle_num == pool_size)) {
                break;
            }
            std::this_thread::yield();
        }
        return 0;
    }

    // return a future, calling future.get() will wait task done and return RetType.
    // commit(fn, args...)
    // commit(std::bind(&Class::mem_fn, &obj))
    // commit(std::mem_fn(&Class::mem_fn, &obj))
    template<class Fn, class... Args>
    auto commit(Fn&& fn, Args&&... args) -> std::future<decltype(fn(args...))> {
        using RetType = decltype(fn(args...));
        auto task = std::make_shared<std::packaged_task<RetType()> >(
            std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...));
        std::future<RetType> future = task->get_future();
        {
            std::lock_guard<std::mutex> locker(_mutex);
            tasks.emplace([task]{
                (*task)();
            });
        }

        _cond.notify_one();
        return future;
    }

public:
    enum Status {
        STOP,
        RUNNING,
        PAUSE,
    };
    int                 pool_size;
    std::atomic<int>    idle_num;
    std::atomic<Status> status;
    std::vector<std::thread>    workers;
    std::queue<Task>            tasks;

protected:
    std::mutex              _mutex;
    std::condition_variable _cond;
};

#endif  // HW_THREAD_POOL_H_

TestCase

#include <stdio.h>
#include <iostream>

#include "hthreadpoo.h"

void print_task(int i){
	std::cout << "thread:" << std::this_thread::get_id() << std::endl;
    printf("task[%d]\n", i);
}

int main(int argc, char** argv){
    HThreadPool tp;
    tp.start();

    for (int i = 0; i < 1000; ++i){
        tp.commit(print_task, i);
    }

    tp.wait();

    return 0;
}
发布了130 篇原创文章 · 获赞 147 · 访问量 29万+
展开阅读全文

C++多线程内存泄漏问题

03-30

在主线程用AfxBeginThread开启子线程时,偶尔会报内存泄漏的错误(单线程没问题) 不是频繁报,10次有1~2次的样子,debug我也不知道怎么跟踪,怀疑是锁的问题加上 CCriticalSection cs; cs.Lock();cs.Unlock();后发现还是不行,求助! ``` /*结构体*/ typedef struct _dlgTag { int nIdx; CString strName; } DLGTAG; /*主线程代码*/ //初始化数组 m_Table.clear(); m_Table.swap(vector<vector<CString>>()); m_Table.resize(nLineCount); for (int i = 0; i < nLineCount; i++) { m_Table[i].resize(3); } //遍历 nThreadNum = 0; nThreadAll = 30; for (int i = 0; i < nLineCount; i++) { //多线程工作 if (nThreadNum < nThreadAll) { DLGTAG *dd = new DLGTAG(); dd->nIdx = i; dd->strName = strLine; AfxBeginThread(LoopWorkThread, (LPVOID)dd); nThreadNum++; continue; } //轮巡线程池 while (1) { int nNull = 0, nBegin = i - nThreadAll, nEnd = i; switch (nBegin) { case 0: nBegin++; nEnd++; break; default: break; } for (int j = nBegin; j < nEnd; j++) { if (m_Table[j][1].IsEmpty()) { nNull++; Sleep(100); } } //已完成数 if (nThreadAll - nNull > 0) { nThreadNum = nNull; i--; break; } } } //遍历结束检查线程是否全部执行完毕 while (1) { int nNull = 0, nDone = 0; for (int i = 0; i < nLineCount; i++) { if (m_Table[i][1].IsEmpty()) { nNull++; Sleep(100); } } nDone = nLineCount - nNull; if (nDone >= nLineCount) { break; } } /*子线程LoopWorkThread代码*/ CCriticalSection cs; UINT LoopWorkThread(LPVOID pParam) { DLGTAG* dlg = (DLGTAG*)pParam; CString strFlag = TestTest(dlg->nIdx, dlg->strName); if (strFlag == "成功") { cs.Lock(); m_Table[dlg->nIdx][2] = 业务代码... } m_Table[dlg->nIdx][1] = strFlag; cs.Unlock(); delete dlg; return 0; } ``` 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 代码科技 设计师: Amelia_0503

分享到微信朋友圈

×

扫一扫,手机浏览