任務隊列簡單實現

實用場景:

例子1:函數

例子2:spa

     生產者-----消費者   之間線程

.hcode

#ifndef __TASK_QUEUE_H__
#define __TASK_QUEUE_H__

typedef struct Task
{
	void* (*run)(void *);	// 任務處理函數
	void* param;			// 附加參數
}Task_t;

typedef struct Task_queue
{
	int head;		// 隊列頭
	int tail;		// 隊列尾
	int size;		// 實際任務數量
	int capcity;	// 任務最大個數
	Task_t*  tasks;	// 任務
}Task_queue_t;


// 建立隊列
// size:任務大小
Task_queue_t *queue_create(int size);

// 隊列是否滿了
bool queue_is_full(Task_queue_t* tq);

// 隊列是否爲空
bool queue_is_empty(Task_queue_t* tq);

// 將任務添加到任務隊列尾部
bool queue_push_tail(Task_queue_t* tq, Task_t* t);

// 取出任務隊列頭部任務
Task_t* queue_pop_head(Task_queue_t* tq);

// 釋放申請的任務隊列
void queue_free(Task_queue_t* tq);

#endif

.cppblog

#include "taskQueue.h"
#include <stdlib.h>

#define DEFAULT_QUEUE_SIZE 65535

Task_queue_t* queue_create(int size)
{
	// 建立隊列結構
	Task_queue_t *tq = (Task_queue_t *)malloc(sizeof(Task_queue_t));
	if (tq != nullptr)
	{
		if (size > 0)
		{
			// 建立任務結構
			tq->tasks = (Task_t *)malloc(size * sizeof(Task_t));
			tq->capcity = size;
		}
		else
		{
			int default_size = DEFAULT_QUEUE_SIZE;
			tq->tasks = (Task_t *)malloc(default_size * sizeof(Task_t));
			tq->capcity = default_size;
		}

		if (tq->tasks == nullptr)
		{
			free(tq);
			return nullptr;
		}

		tq->head = tq->tail = tq->size = 0;
	}

	return tq;
}

bool queue_is_full(Task_queue_t* tq)
{
	return tq->size == tq->capcity;
}

bool queue_is_empty(Task_queue_t* tq)
{
	return tq->size == 0;
}

bool queue_push_tail(Task_queue_t* tq, Task_t* t)
{
	if (!queue_is_full(tq))
	{
		tq->tasks[tq->tail].run = t->run;
		tq->tasks[tq->tail].param = t->param;

		//tq->tail++; 錯誤示範  這樣沒法複用

		// 當任務滿最大值時,取出最前面任務後,
		// 當又須要添加新的任務時能夠複用前面的任務結構
		tq->tail = (tq->tail + 1) % (tq->capcity);
		
		tq->size++;
		return true;
	}

	return false;
}

Task_t* queue_pop_head(Task_queue_t* tq)
{
	Task_t* t = nullptr;
	if (!queue_is_empty(tq))
	{
		t = &(tq->tasks[tq->head]);

		//tq->head--; 錯誤 這樣沒法複用
		tq->head = (tq->head + 1) % (tq->capcity);

		tq->size--;
	}

	return t;
}

void queue_free(Task_queue_t* tq)
{
	if (tq != nullptr)
	{
		free(tq->tasks);
		free(tq);
	}
}

注意:其餘線程使用時注意push,pop須要同步!

相關文章
相關標籤/搜索