[C] 模拟线程池

版权声明:本文为博主原创文章,若有错误之处望大家批评指正!转载需附上原文链接,谢谢! https://blog.csdn.net/summer_dew/article/details/84955170
/*
# 题目
【线程池】是一种多任务处理模型,由一个任务队列和若干工作线程组成

【任务队列】任务队列包含若干任务
1. 每个任务包含指向任务数据的指针和处理该任务的函数指针
2. 可以向任务队列追加新任务

【工作线程】每个工作线程运行一个任务队列处理函数
1. 核心功能是从队列中获取一个可用任务
	1. 如果队列中有任务则执行
	2. 如果队列为空,则调用休眠函数休眠若干时间后继续循环获取任务

【说明】不考虑线程同步问题

 # 思考(×)
 【解题方法】离散事件的模拟
 【类似问题】[银行窗口模拟](https://blog.csdn.net/summer_dew/article/details/84452073)
 【思考】以银行窗口为例

 1. 任务队列:对应为 银行的窗口
 2. 工作线程:对应为 客户办理业务
 3. 窗口闲置时,即 工作线程休眠的时候
 */
#include<stdio.h>
#include<stdlib.h>
#include<time.h>	//rand()
#include<windows.h> //sleep()

typedef struct task{
	void* pTaskData; /* 任务数据 */
	void (*fnTaskExec)(void *pTaskData); /* 任务处理函数指针 */
	struct task *next;
}Task; //任务
typedef struct{
	Task* front; //指向头结点
	Task* rear;  //最后一个结点
}TaskQueue; //工作线程:有头结点的队列

typedef struct thread{
	int ID;		//线程ID
	int state;	//线程状态
	Task* currentTask; //当前线程所处理的任务
}Thread;


TaskQueue taskQueue;
/* 初始化任务队列 */
int InitTask() {
	Task *head;
	head = (Task *)malloc(sizeof(Task));
	if (!head) exit(0);
	head->next = NULL;
	taskQueue.front = taskQueue.rear = NULL;
	return 1;
}
/* 向任务队列追加新的任务 */
int AddTask(Task *newTask) {
	newTask->next = NULL;
	taskQueue.rear->next = newTask;
	taskQueue.rear = newTask;
	return 1;
}

/* 向任务队列取任务 */
Task* PopTask() {
	Task *first;
	if (taskQueue.front->next==NULL) { //队列除了头结点front,没有其他结点
		return NULL;
	} else {
		first = taskQueue.front->next; //第一个
		taskQueue.front->next = first->next; //出队列
		if (taskQueue.rear == first) { //队列中只有一个元素
			taskQueue.rear = taskQueue.front; //没有任务了
		}
		return first;
	}
}

/* 工作线程:队列处理函数 */
int handleTask(Thread *pThread) {
	//从任务队列中获取一个可用任务
	// 有,执行
	// 没有,睡眠
	Task *task;
	while (1) { //一直循环取任务
		task = PopTask();
		if (task == NULL) { //当前没有任务
			srand( time(NULL) ); //时间种子
			pThread->state = 0; pThread->currentTask = NULL;//没有在工作
			Sleep( (int)rand() ); //睡眠
		} else { //当前有任务
			pThread->state = 1; //正在执行任务
			pThread->currentTask = task; //执行的任务
			(*task->fnTaskExec)(task->pTaskData); //执行任务
			// 执行结束
			pThread->state = 0;
			pThread->currentTask = NULL;
			task = NULL;
		}
	}
	return 1;
}

// 此种写法,需要用多线程,这里就不调用了
// 如果需要用单线程模拟这个过程,可以用离散事件的思想
int main() {
	return 0;
}

猜你喜欢

转载自blog.csdn.net/summer_dew/article/details/84955170