线程池+日志

lockGuard.hpp

#include <iostream>
#include <pthread.h>


class Mutex
{
public:
    Mutex(pthread_mutex_t *pmtx)
        : _pmtx(pmtx)
    {
    }
    void lock()
    {
        //std::cout << "要进行加锁:" << std::endl;
        pthread_mutex_lock(_pmtx);
    }
    void unlock()
    {
        //std::cout << "要进行解锁:" << std::endl;
        pthread_mutex_unlock(_pmtx);
    }

private:
    pthread_mutex_t *_pmtx;
};

//RAII风格的加锁方式
class lockGuard
{
public:
    lockGuard(pthread_mutex_t *pmtx)
        : _mtx(pmtx)
    {
        _mtx.lock();
    }
    ~lockGuard()
    {
        _mtx.unlock();
    }

private:
    Mutex _mtx;
};

log.hpp

#pragma once
#include <iostream>  
#include <string>  
#include <cstdarg>  
#include <cstdio>  
#include <ctime>

#define DEBUG 0
#define NORMAL 1  
#define WARNING 2  
#define ERROR 3  
#define FATAL 4  

const char* gLevelMap[5] = { "DEBUG","NORMAL","WARNING","ERROR","FATAL"};

#define LOGFILE "./threadpool.log"

void logMessage(int level, const char* format, ...)
{
    char stdBuffer[1024];//标准部分
    time_t timestamp = time(nullptr);
    struct tm* time=localtime(&timestamp);
    snprintf(stdBuffer,sizeof stdBuffer, "[%s][%ld]",gLevelMap[level],timestamp);



    char logBuffer[64]; // 自定义部分
    va_list args;
    va_start(args, format);
    vsnprintf(logBuffer, sizeof(logBuffer), format, args); // 使用 vsnprintf 而不是 vsprintf  
    va_end(args);

    FILE* fp=fopen(LOGFILE,"a");

    //打印到显示器
    //printf("%s %s\n",stdBuffer,logBuffer);

    //打印到指定文件
    fprintf(fp,"%s%s\n",stdBuffer,logBuffer);

    fclose(fp);
}


Makefile

cp: testMain.cc
	g++ -o cp testMain.cc -std=c++11 -lpthread  
  
.PHONY: clean  
  
clean:  
	rm -rf cp

Task.hpp

#include <iostream>
#include <string>
#include "log.hpp"

// typedef std::function<int(int, int)> func_t;

typedef int (*Func_t)(int, int);

int add(int x, int y)
{
    return x + y;
}

class Task
{
public:
    Task() {}

    Task(int x, int y, Func_t func = add)
        : _x(x), _y(y), _func(func)
    {
    }

    void operator()(const std::string& name)
    {
        logMessage(WARNING,"%s处理完成: %d+%d=%d | %s |%d",name.c_str(),_x,_y,_func(_x,_y),__FILE__,__LINE__);
    }

private:
    int _x;
    int _y;
    Func_t _func;
};

testMain.cc

#include "threadPool.hpp"
#include "Task.hpp"
#include "log.hpp"


int main()
{
    //logMessage(0,"%s %d %c","我爱你",520,'u');
    srand((unsigned int)time(nullptr));
    ThreadPool<Task> *tp = new ThreadPool<Task>(10);
    tp->run();

    while (true)
    {
        int x = rand() % 100 + 1;
        usleep(7721);
        int y = rand() % 100 + 1;
        Task t(x,y,[](int x,int y)->int{return x+y;});

        logMessage(DEBUG,"制作任务完成: %d+%d=?",x,y);

        tp->pushTask(t);
    }
}

thread.hpp

#include <iostream>
#include <pthread.h>
#include <string>
// #include <functional>

// typedef std::function<void* (void*)> func_t;

typedef void *(*func_t)(void *);

class ThreadData
{
public:
    std::string _name;
    void *_args;
};

class Thread
{
public:
    Thread(int num, func_t callback, void *args)
        : _func(callback)
    {
        std::string str = "Thread " + std::to_string(num);
        _tdata._name = str;
        _tdata._args = args;
    }

    void start()
    {
        pthread_create(&_tid, nullptr, _func, &_tdata);
    }

    void join()
    {
        pthread_join(_tid, nullptr);
    }

    std::string name()
    {
        return _tdata._name;
    }

    ~Thread()
    {
        pthread_join(_tid, nullptr);
    }

public:
    // std::string _name;
    // void *_args;
    ThreadData _tdata;
    pthread_t _tid;
    func_t _func;
};

threadPool.hpp

#include <iostream>
#include <pthread.h>
#include <vector>
#include <queue>
#include <unistd.h>

#include "thread.hpp"
#include "lockGuard.hpp"
#include "log.hpp"

const int default_capacity = 5;

template <class T>
class ThreadPool
{
public:
    ThreadPool(int capacity = default_capacity)
        : _capacity(capacity)
    {
        pthread_mutex_init(&_mtx, nullptr);
        pthread_cond_init(&_cond, nullptr);
        for (int i = 0; i < capacity; i++)
        {
            Thread *ptd = new Thread(i + 1, routine, this);
            _threads.push_back(ptd);
        }
    }

    bool isEmpty()
    {
        return _task_queue.empty();
    }

    static void *routine(void *arg)
    {
        ThreadData *td = (ThreadData *)arg;
        ThreadPool<T> *tp = (ThreadPool<T> *)td->_args;
        while (true)
        {
            lockGuard lockguard(&tp->_mtx);
            if (tp->isEmpty())
            {
                pthread_cond_wait(&tp->_cond, &tp->_mtx);
            }
            T task = tp->_task_queue.front();
            tp->_task_queue.pop();
            task(td->_name);
            sleep(1);
        }
    }

    void run()
    {
        for (auto &iter : _threads)
        {
            iter->start();
            //std::cout << iter->name() << " 启动成功" << std::endl;
            logMessage(NORMAL,"%s%s",iter->name().c_str(),"启动成功");
        }
    }

    void pushTask(const T &task)
    {
        lockGuard lockguard(&_mtx);
        _task_queue.push(task);
        pthread_cond_signal(&_cond);
    }

    void joins()
    {
        for (int i = 0; i < _capacity; i++)
        {
            _threads[i]->join();
        }
    }

    ~ThreadPool()
    {
        for (int i = 0; i < _capacity; i++)
        {
            _threads[i]->join();
            delete _threads[i];
        }
        pthread_mutex_destroy(&_mtx);
        pthread_cond_destroy(&_cond);
    }

private:
    std::vector<Thread *> _threads; // 存放线程
    size_t _capacity;

    std::queue<T> _task_queue; // 存放任务

    pthread_mutex_t _mtx;
    pthread_cond_t _cond;
};

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值