C++ 数据结构算法 学习笔记(9) - 队列及企业级应用 (续2)
队列的企业级应用案例
线程池中的任务队列
线程池 - 由一个任务队列和一组处理队列的线程组成。一旦工作进程需要处理某个可能“阻塞”的 操作,不用自己操作,将其作为一个任务放到线程池的队列,接着会被某个空闲线程提取处理。
代码实现
#include <stdio.h>
#include <assert.h>
#include <Windows.h>
#include <iostream>
#include <iomanip>
using namespace std;
#define MaxSize 1000
typedef struct _QNode {
int id;
void (*handler)(void);
struct _QNode* next;
}QNode;
typedef QNode* QueuePtr;
typedef struct Queue
{
int length;
QueuePtr front;
QueuePtr rear;
}LinkQueue;
QueuePtr thread_task_alloc()
{
QNode* task;
task = (QNode*)calloc(1, sizeof(QNode));
if (task == NULL) {
return NULL;
}
return task;
}
void InitQueue(LinkQueue* LQ)
{
if (!LQ) return;
LQ->length = 0;
LQ->front = LQ->rear = NULL;
}
int IsEmpty(LinkQueue * LQ)
{
if (!LQ) return 0;
if (LQ->front == NULL)
{
return 1;
}
return 0;
}
int IsFull(LinkQueue* LQ)
{
if (!LQ) return 0;
if (LQ->length == MaxSize)
{
return 1;
}
return 0;
}
int EnterQueue(LinkQueue* LQ, QNode* node) {
if (!LQ || !node) return 0;
if (IsFull(LQ)) {
cout << "Not able to insert the task " << node->id << ", queue is already FULL!" << endl;
return 0;
}
node->next = NULL;
if (IsEmpty(LQ)) {
LQ->front = LQ->rear = node;
}
else {
LQ->rear->next = node;
LQ->rear = node;
}
LQ->length++;
return 1;
}
QNode * PopQueue(LinkQueue * LQ) {
QNode* tmp = NULL;
if (!LQ || IsEmpty(LQ)) {
cout << "Queue is EMPTY!" << endl;
return 0;
}
tmp = LQ->front;
LQ->front = tmp->next;
if (!LQ->front) LQ->rear = NULL;
LQ->length--;
return tmp;
}
void PrintQueue(LinkQueue* LQ)
{
QueuePtr tmp;
if (!LQ) return;
if (LQ->front == NULL) {
cout << "Queue is EMPTY";
return;
}
tmp = LQ->front;
while (tmp)
{
cout << setw(4) << tmp->id;
tmp = tmp->next;
}
cout << endl;
}
int getLength(LinkQueue* LQ) {
if (!LQ) return 0;
return LQ->length;
}
void task1() {
printf("I am Task1 ...\n");
}
void task2() {
printf("I am Task2 ...\n");
}
int main()
{
LinkQueue* LQ = new LinkQueue;
QNode* task = NULL;
InitQueue(LQ);
task = thread_task_alloc();
task->id = 1;
task->handler = &task1;
EnterQueue(LQ, task);
task = thread_task_alloc();
task->id = 2;
task->handler = &task2;
EnterQueue(LQ, task);
cout << "Queue Element total have" << getLength(LQ) << endl;
PrintQueue(LQ);
cout << endl;
while ((task = PopQueue(LQ))) {
task->handler();
delete task;
}
delete LQ;
system("pause");
return 0;
}
注: 其实这个的做法和之前的链式队列很像,只是这个有函数指针