项目介绍:
这是一个基于线程池+Epoll的IO多路复用、非阻塞IO技术,的高并发服务器框架。
项目模块
- 一个线程池
- 一个给线程池使用的任务队列
- 一个服务器程序
- 其他待定
任务队列实现
今天先实现一个任务队列,这个任务队列是给线程池使用的。主要包括两个类。
类 | 成员 | 备注 |
---|---|---|
Task | callback function |
using callback=void*( )(void )//任务所执行的函数 |
Task | void *arg | 任务执行函数的参数 |
Task | Task() | 无参构造 |
Task | Task(callback f,void* a) | 提供任务执行函数和函数参数来构造一个Task |
TaskQueue | queue<Task> m_queue | 一个用来存储任务的队列 |
TaskQueue | pthread_mutex_t m_mutex | 一个互斥锁,添加和取出任务是原子操作 |
TaskQueue | TaskQueue() | 初始化m_mutex |
TaskQueue | ~TaskQueue() | 销毁m_mutex |
TaskQueue | void addTask(task) | 添加任务 |
TaskQueue | Task takeTask() | 取出任务 |
TaskQueue | size_t size() | 当前任务队列的任务数量 |
一些注意的地方
- 添加和取出任务是原子操作,需加锁和解锁。
- 互斥锁需在任务队列的构造函数中初始化,在析构函数中销毁
- 任务Task类实际上是封装了要执行的函数和它的参数,TaskQueue类实际上是封装了一个储存任务的队列,并用锁实现原子操作。
TaskQueue.h
#pragma once
#include<queue>
#include<pthread.h>
using namespace std;
using callback= void*(*)(void*);
struct Task{
Task():function(nullptr),arg(nullptr){}
Task(callback f,void * targ):function(f),arg(targ) {}
callback function;
void* arg;
};
class TaskQueue{
public:
TaskQueue();
~TaskQueue();
void addTask(Task &task);
Task takeTask();
size_t size();
private:
pthread_mutex_t m_mutex;
queue<Task> m_queue;
};
TaskQueue.cpp
#include"TaskQueue.h"
#include<iostream>
using std::cout;
using std::endl;
TaskQueue::TaskQueue(){
pthread_mutex_init(&m_mutex,NULL);
}
TaskQueue::~TaskQueue(){
pthread_mutex_destroy(&m_mutex);
}
void TaskQueue::addTask(Task &task){
pthread_mutex_lock(&m_mutex);
m_queue.push(task);
pthread_mutex_unlock(&m_mutex);
cout<<"add task, current task number is "<<m_queue.size()<<endl;
}
Task TaskQueue::takeTask(){
pthread_mutex_lock(&m_mutex);
Task task;
if(m_queue.size()!=0){
task=m_queue.front();
m_queue.pop();
}
pthread_mutex_unlock(&m_mutex);
cout<<"take task, current task number is "<<m_queue.size()<<endl;
return task;
}
size_t TaskQueue::size(){
return m_queue.size();
}
版权声明:本文为SWELER原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。