面试题答案
一键面试设计思路
- 任务队列设计:采用两个任务队列,一个用于高优先级任务,另一个用于低优先级任务。使用链表结构实现任务队列,方便插入和删除操作。
- 线程池管理:线程池中的线程从两个任务队列中获取任务。高优先级任务队列优先被处理,但为了防止低优先级任务饿死,设置一个时间片机制,定期处理低优先级任务队列。
- 资源分配:根据任务优先级动态调整CPU时间片分配。高优先级任务分配更多的CPU时间,通过调度算法(如CFS调度算法的思想)进行模拟实现。内存分配则在任务执行时按需分配,注意内存的及时释放,防止内存泄漏。
实现方法
- 数据结构定义:
#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;
- 任务队列操作函数:
// 初始化任务队列
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;
}
- 线程执行函数:
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;
}
- 线程池初始化与销毁:
// 初始化线程池
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);
}
- 示例任务函数:
void sampleTask(void* arg) {
int num = *((int *)arg);
printf("Task %d is running\n", num);
sleep(1); // 模拟任务执行
printf("Task %d is finished\n", num);
}
- 主函数测试:
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;
}
上述代码通过两个任务队列实现了不同优先级任务的管理,并通过线程池中的线程按规则从队列获取任务执行,同时使用时间片机制避免低优先级任务饿死。