当前位置:首页 > C > 正文

C语言任务队列实现(从零开始构建高效任务调度系统)

在嵌入式开发、服务器编程或高性能计算中,C语言任务队列是一种非常实用的数据结构。它能够帮助开发者高效地管理待处理的任务,尤其在多线程任务调度场景下显得尤为重要。本教程将手把手教你用C语言从零实现一个线程安全的任务队列,即使你是编程小白也能轻松上手。

C语言任务队列实现(从零开始构建高效任务调度系统) C语言任务队列 多线程任务调度 C语言并发编程 任务队列实现 第1张

什么是任务队列?

任务队列本质上是一个先进先出(FIFO)的队列,用于存储待执行的“任务”。每个任务通常是一个函数指针及其参数。生产者线程将任务放入队列,消费者线程从队列中取出并执行任务。这种模式广泛应用于C语言并发编程中。

设计思路

我们将使用链表实现队列,并通过互斥锁(mutex)和条件变量(condition variable)来保证线程安全。主要包含以下组件:

  • 任务结构体(task):包含函数指针和参数
  • 队列节点(queue node):指向任务和下一个节点
  • 任务队列结构体(task_queue):包含头尾指针、锁和条件变量
  • 初始化、入队、出队、销毁等操作函数

完整代码实现

以下是完整的C语言任务队列实现代码:

// task_queue.h#ifndef TASK_QUEUE_H#define TASK_QUEUE_H#include <pthread.h>#include <stdlib.h>typedef struct task {    void (*func)(void*);    void* arg;} task_t;typedef struct queue_node {    task_t* task;    struct queue_node* next;} queue_node_t;typedef struct {    queue_node_t* head;    queue_node_t* tail;    pthread_mutex_t mutex;    pthread_cond_t cond;    int size;} task_queue_t;void task_queue_init(task_queue_t* queue);void task_queue_push(task_queue_t* queue, task_t* task);task_t* task_queue_pop(task_queue_t* queue);void task_queue_destroy(task_queue_t* queue);#endif // TASK_QUEUE_H// task_queue.c#include "task_queue.h"void task_queue_init(task_queue_t* queue) {    queue->head = NULL;    queue->tail = NULL;    queue->size = 0;    pthread_mutex_init(&queue->mutex, NULL);    pthread_cond_init(&queue->cond, NULL);}void task_queue_push(task_queue_t* queue, task_t* task) {    queue_node_t* new_node = (queue_node_t*)malloc(sizeof(queue_node_t));    new_node->task = task;    new_node->next = NULL;    pthread_mutex_lock(&queue->mutex);    if (queue->tail == NULL) {        queue->head = queue->tail = new_node;    } else {        queue->tail->next = new_node;        queue->tail = new_node;    }    queue->size++;    pthread_mutex_unlock(&queue->mutex);    pthread_cond_signal(&queue->cond); // 唤醒等待的消费者线程}task_t* task_queue_pop(task_queue_t* queue) {    pthread_mutex_lock(&queue->mutex);    // 如果队列为空,等待直到有任务    while (queue->head == NULL) {        pthread_cond_wait(&queue->cond, &queue->mutex);    }    queue_node_t* node = queue->head;    task_t* task = node->task;    queue->head = queue->head->next;    if (queue->head == NULL) {        queue->tail = NULL;    }    queue->size--;    pthread_mutex_unlock(&queue->mutex);    free(node);    return task;}void task_queue_destroy(task_queue_t* queue) {    while (queue->head != NULL) {        queue_node_t* temp = queue->head;        queue->head = queue->head->next;        free(temp->task);        free(temp);    }    pthread_mutex_destroy(&queue->mutex);    pthread_cond_destroy(&queue->cond);}  

使用示例

下面是一个简单的使用示例,展示如何创建任务并加入队列:

#include <stdio.h>#include <unistd.h>#include "task_queue.h"void print_message(void* msg) {    printf("Task executed: %s\n", (char*)msg);}int main() {    task_queue_t queue;    task_queue_init(&queue);    // 创建任务    task_t* task1 = (task_t*)malloc(sizeof(task_t));    task1->func = print_message;    task1->arg = "Hello from task 1!";    task_t* task2 = (task_t*)malloc(sizeof(task_t));    task2->func = print_message;    task2->arg = "Hello from task 2!";    // 入队    task_queue_push(&queue, task1);    task_queue_push(&queue, task2);    // 出队并执行    task_t* t1 = task_queue_pop(&queue);    t1->func(t1->arg);    free(t1);    task_t* t2 = task_queue_pop(&queue);    t2->func(t2->arg);    free(t2);    task_queue_destroy(&queue);    return 0;}  

编译与运行

将上述代码保存为 task_queue.htask_queue.cmain.c,然后使用以下命令编译(注意链接pthread库):

gcc -o task_queue main.c task_queue.c -lpthread

运行程序后,你将看到任务按顺序执行的输出。

总结

通过本教程,你已经掌握了如何在C语言中实现一个线程安全的任务队列。这项技能对于理解多线程任务调度和提升C语言并发编程能力至关重要。你可以在此基础上扩展功能,比如添加任务优先级、超时机制或批量处理能力。

记住,良好的C语言任务队列实现是构建高性能、响应迅速的系统的基础。希望这篇教程能为你打开任务队列实现的大门!