Fork me on GitHub

应用案例——线程池中的任务队列

线程池-由一个任务队列和一组处理队列的线程组成。一旦工作进程需要处理某个可能“阻塞”的操作,不用自己操作,将其作为一个任务放到线程池的队列,接着会被某个空闲线程提取处理。

 

 

  1 #include <stdio.h>
  2 #include <assert.h>
  3 #include <Windows.h>
  4 #include <iostream>
  5 #include <iomanip>
  6 
  7 using namespace std;
  8 
  9 #define MaxSize 1000    //队列的最大容量
 10 
 11 typedef struct _QNode    //任务结点结构
 12 {
 13     int    id;
 14     void(*handler)(void);
 15     struct _QNode* next;
 16 }QNode;
 17 
 18 typedef QNode* QueuePtr;
 19 
 20 typedef struct Queue
 21 {
 22     int    length;            //队列的长度
 23     QueuePtr front;        //队头指针
 24     QueuePtr rear;        //队尾指针
 25 }LinkQueue;
 26 
 27 //分配线程执行的任务节点
 28 QueuePtr thread_task_alloc()
 29 {
 30     QNode* task;
 31     task = (QNode*)calloc(1, sizeof(QNode));
 32     if (task == NULL)
 33     {
 34         return NULL;
 35     }
 36     return task;
 37 }
 38 
 39 //队列初始化,将队列初始化为空队列
 40 void InitQueue(LinkQueue* LQ)
 41 {
 42     if (!LQ) return;
 43     LQ->length = 0;
 44     LQ->front = LQ->rear = NULL; //把对头和队尾指针同时置0
 45 }
 46 
 47 //判断队列为空
 48 int IsEmpty(LinkQueue* LQ)
 49 {
 50     if (!LQ) return 0;
 51     if (LQ->front == NULL)
 52     {
 53         return 1;
 54     } return 0;
 55 }
 56 
 57 //判断队列是否为满
 58 int IsFull(LinkQueue* LQ)
 59 {
 60     if (!LQ) return 0;
 61     if (LQ->length == MaxSize)
 62     {
 63         return 1;
 64     } return 0;
 65 }
 66 
 67 //入队,将元素data插入到队列LQ中
 68 int EnterQueue(LinkQueue* LQ, QNode* node)
 69 {
 70     if (!LQ || !node) return 0;
 71     if (IsFull(LQ))
 72     {
 73         cout << "无法插入任务 " << node->id << ", 队列已满!" << endl; return 0;
 74     } node->next = NULL;
 75     if (IsEmpty(LQ))            //空队列
 76     {
 77         LQ->front = LQ->rear = node;
 78     }
 79     else
 80     {
 81         LQ->rear->next = node;        //在队尾插入节点qNode
 82         LQ->rear = node;            //队尾指向新插入的节点
 83     }
 84     LQ->length++;
 85     return 1;
 86 }
 87 
 88 //出队,将队列中队头的节点出队,返回头节点
 89 QNode* PopQueue(LinkQueue* LQ)
 90 {
 91     QNode* tmp = NULL;
 92     if (!LQ || IsEmpty(LQ))
 93     {
 94         cout << "队列为空!" << endl;
 95         return 0;
 96     } tmp = LQ->front;
 97 
 98     LQ->front = tmp->next;
 99 
100     if (!LQ->front)
101     {
102         LQ->rear = NULL;//如果对头出列后不存在其他元素,则rear节点也要置空
103         LQ->length--;
104     }
105     return tmp;
106 }
107 
108 //打印队列中的各元素
109 void PrintQueue(LinkQueue* LQ)
110 {
111     QueuePtr tmp;
112     if (!LQ) return;
113     if (LQ->front == NULL)
114     {
115         cout << "队列为空!"; return;
116     }
117     tmp = LQ->front; 
118     while (tmp)
119     {
120         cout << setw(4) << tmp->id;
121         tmp = tmp->next;
122     }
123     cout << endl;
124 }
125 
126 //获取队列中元素的个数
127 int getLength(LinkQueue* LQ)
128 {
129     if (!LQ) return 0;
130     return LQ->length;
131 }
132 
133 void task1()
134 {
135     printf("我是任务1 ...\n");
136 }
137 void task2()
138 {
139     printf("我是任务2 ...\n");
140 }
141 
142 
143 int main()
144 {
145     LinkQueue* LQ = new LinkQueue; 
146     QNode* task = NULL;
147     //初始化队列
148     InitQueue(LQ);
149     
150     //任务1入队
151     task = thread_task_alloc();
152     task->id = 1; 
153     task->handler = &task1; 
154     EnterQueue(LQ, task);
155     
156     //任务2入队
157     task = thread_task_alloc();
158     task->id = 2; 
159     task->handler = &task2; 
160     EnterQueue(LQ, task);
161     
162     //打印任务队列中的元素
163     printf("队列中的元素(总共%d 个):", getLength(LQ));
164     PrintQueue(LQ); 
165     cout << endl;
166     
167     //执行任务
168     while ((task = PopQueue(LQ)))
169     {
170         task->handler(); 
171         delete task;
172     }
173     
174     //清理资源 
175     delete LQ;
176     system("pause");
177     return 0;
178 }

 

 

 

 

 

=================================================================================================================

 

posted @ 2020-09-02 16:08  索智源  阅读(1466)  评论(0编辑  收藏  举报