MST

星途 面试题库

面试题:C语言线程池的基本实现思路

请简述在C语言中实现线程池的基本步骤和关键数据结构,假设要设计一个能处理一系列任务的线程池,每个任务是一个函数指针及其参数,你会如何着手实现?
17.3万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

基本步骤

  1. 初始化线程池:创建一定数量的线程,并将它们设置为等待任务状态。
  2. 任务队列管理:创建一个任务队列,用于存放待处理的任务。
  3. 任务提交:将任务添加到任务队列中,当有任务时唤醒等待的线程。
  4. 线程执行任务:线程从任务队列中取出任务并执行,执行完毕后继续等待新任务。
  5. 销毁线程池:当不再需要线程池时,停止所有线程并释放相关资源。

关键数据结构

  1. 任务结构体
typedef struct {
    void (*func)(void*);  // 函数指针
    void *arg;            // 函数参数
} Task;
  1. 任务队列结构体
typedef struct {
    Task *tasks;          // 任务数组
    int front;            // 队列头
    int rear;             // 队列尾
    int capacity;         // 队列容量
    int size;             // 当前任务数量
} TaskQueue;
  1. 线程池结构体
typedef struct {
    pthread_t *threads;   // 线程数组
    TaskQueue queue;      // 任务队列
    int is_shutdown;      // 是否关闭线程池标识
    pthread_mutex_t mutex;
    pthread_cond_t cond;
} ThreadPool;

实现思路

  1. 初始化线程池
    • 分配 ThreadPool 结构体内存。
    • 初始化任务队列,分配 Task 数组内存。
    • 初始化互斥锁和条件变量。
    • 创建指定数量的线程,每个线程执行工作函数。
  2. 工作函数
    • 线程循环等待任务,通过 pthread_cond_wait 等待任务队列有任务。
    • 当有任务时,获取任务队列中的任务并执行。
  3. 任务提交函数
    • 向任务队列中添加任务,需要加锁保护任务队列。
    • 添加任务后,通过 pthread_cond_signal 唤醒一个等待的线程。
  4. 销毁线程池
    • 设置关闭标识,唤醒所有等待的线程。
    • 等待所有线程执行完毕,释放相关内存,销毁互斥锁和条件变量。