MST

星途 面试题库

面试题:C语言Linux线程池任务优先级与系统资源分配的协同优化

在Linux系统中,使用C语言实现的线程池模型里,不同优先级的任务对系统资源(如CPU、内存)的需求不同。如何在保证高优先级任务优先执行的同时,合理分配系统资源,避免低优先级任务长时间得不到执行或系统资源耗尽?请详细阐述设计思路和实现方法,并给出核心代码示例。
26.0万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 任务队列设计:采用两个任务队列,一个用于高优先级任务,另一个用于低优先级任务。使用链表结构实现任务队列,方便插入和删除操作。
  2. 线程池管理:线程池中的线程从两个任务队列中获取任务。高优先级任务队列优先被处理,但为了防止低优先级任务饿死,设置一个时间片机制,定期处理低优先级任务队列。
  3. 资源分配:根据任务优先级动态调整CPU时间片分配。高优先级任务分配更多的CPU时间,通过调度算法(如CFS调度算法的思想)进行模拟实现。内存分配则在任务执行时按需分配,注意内存的及时释放,防止内存泄漏。

实现方法

  1. 数据结构定义
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

// 任务结构体
typedef struct Task {
    void (*func)(void*);
    void *arg;
    int priority; // 1表示高优先级,0表示低优先级
    struct Task *next;
} Task;

// 任务队列结构体
typedef struct TaskQueue {
    Task *head;
    Task *tail;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
} TaskQueue;

// 线程池结构体
typedef struct ThreadPool {
    pthread_t *threads;
    TaskQueue highPriorityQueue;
    TaskQueue lowPriorityQueue;
    int threadCount;
    int isShutdown;
} ThreadPool;
  1. 任务队列操作函数
// 初始化任务队列
void initTaskQueue(TaskQueue *queue) {
    queue->head = NULL;
    queue->tail = NULL;
    pthread_mutex_init(&queue->mutex, NULL);
    pthread_cond_init(&queue->cond, NULL);
}

// 添加任务到任务队列
void addTask(TaskQueue *queue, Task *task) {
    pthread_mutex_lock(&queue->mutex);
    if (queue->tail == NULL) {
        queue->head = queue->tail = task;
    } else {
        queue->tail->next = task;
        queue->tail = task;
    }
    pthread_cond_signal(&queue->cond);
    pthread_mutex_unlock(&queue->mutex);
}

// 从任务队列获取任务
Task* getTask(TaskQueue *queue) {
    pthread_mutex_lock(&queue->mutex);
    while (queue->head == NULL) {
        pthread_cond_wait(&queue->cond, &queue->mutex);
    }
    Task *task = queue->head;
    queue->head = task->next;
    if (queue->head == NULL) {
        queue->tail = NULL;
    }
    pthread_mutex_unlock(&queue->mutex);
    return task;
}
  1. 线程执行函数
void* threadFunction(void* arg) {
    ThreadPool *pool = (ThreadPool *)arg;
    while (1) {
        Task *task = NULL;
        pthread_mutex_lock(&pool->highPriorityQueue.mutex);
        if (pool->highPriorityQueue.head != NULL) {
            task = getTask(&pool->highPriorityQueue);
        }
        pthread_mutex_unlock(&pool->highPriorityQueue.mutex);

        if (task == NULL) {
            static int lowPriorityCounter = 0;
            lowPriorityCounter++;
            if (lowPriorityCounter % 10 == 0) { // 每10次循环处理一次低优先级任务
                pthread_mutex_lock(&pool->lowPriorityQueue.mutex);
                if (pool->lowPriorityQueue.head != NULL) {
                    task = getTask(&pool->lowPriorityQueue);
                }
                pthread_mutex_unlock(&pool->lowPriorityQueue.mutex);
                lowPriorityCounter = 0;
            }
        }

        if (task == NULL) {
            pthread_mutex_lock(&pool->highPriorityQueue.mutex);
            pthread_mutex_lock(&pool->lowPriorityQueue.mutex);
            if (pool->highPriorityQueue.head == NULL && pool->lowPriorityQueue.head == NULL && pool->isShutdown) {
                pthread_mutex_unlock(&pool->lowPriorityQueue.mutex);
                pthread_mutex_unlock(&pool->highPriorityQueue.mutex);
                break;
            }
            pthread_mutex_unlock(&pool->lowPriorityQueue.mutex);
            pthread_mutex_unlock(&pool->highPriorityQueue.mutex);
            continue;
        }

        task->func(task->arg);
        free(task);
    }
    return NULL;
}
  1. 线程池初始化与销毁
// 初始化线程池
ThreadPool* createThreadPool(int threadCount) {
    ThreadPool *pool = (ThreadPool *)malloc(sizeof(ThreadPool));
    pool->threadCount = threadCount;
    pool->threads = (pthread_t *)malloc(threadCount * sizeof(pthread_t));
    pool->isShutdown = 0;

    initTaskQueue(&pool->highPriorityQueue);
    initTaskQueue(&pool->lowPriorityQueue);

    for (int i = 0; i < threadCount; i++) {
        pthread_create(&pool->threads[i], NULL, threadFunction, pool);
    }

    return pool;
}

// 销毁线程池
void destroyThreadPool(ThreadPool *pool) {
    pool->isShutdown = 1;
    pthread_mutex_lock(&pool->highPriorityQueue.mutex);
    pthread_cond_broadcast(&pool->highPriorityQueue.cond);
    pthread_mutex_unlock(&pool->highPriorityQueue.mutex);

    pthread_mutex_lock(&pool->lowPriorityQueue.mutex);
    pthread_cond_broadcast(&pool->lowPriorityQueue.cond);
    pthread_mutex_unlock(&pool->lowPriorityQueue.mutex);

    for (int i = 0; i < pool->threadCount; i++) {
        pthread_join(pool->threads[i], NULL);
    }

    free(pool->threads);
    pthread_mutex_destroy(&pool->highPriorityQueue.mutex);
    pthread_cond_destroy(&pool->highPriorityQueue.cond);
    pthread_mutex_destroy(&pool->lowPriorityQueue.mutex);
    pthread_cond_destroy(&pool->lowPriorityQueue.cond);
    free(pool);
}
  1. 示例任务函数
void sampleTask(void* arg) {
    int num = *((int *)arg);
    printf("Task %d is running\n", num);
    sleep(1); // 模拟任务执行
    printf("Task %d is finished\n", num);
}
  1. 主函数测试
int main() {
    ThreadPool *pool = createThreadPool(3);

    int num1 = 1, num2 = 2, num3 = 3, num4 = 4;
    Task task1 = {sampleTask, &num1, 1, NULL};
    Task task2 = {sampleTask, &num2, 0, NULL};
    Task task3 = {sampleTask, &num3, 1, NULL};
    Task task4 = {sampleTask, &num4, 0, NULL};

    addTask(&pool->highPriorityQueue, &task1);
    addTask(&pool->lowPriorityQueue, &task2);
    addTask(&pool->highPriorityQueue, &task3);
    addTask(&pool->lowPriorityQueue, &task4);

    sleep(5);
    destroyThreadPool(pool);

    return 0;
}

上述代码通过两个任务队列实现了不同优先级任务的管理,并通过线程池中的线程按规则从队列获取任务执行,同时使用时间片机制避免低优先级任务饿死。