【学习记录】c完整线程池实现

前言

c实现线程池,初步测试无误,采用双端队列,和任务偷取,任务优先加入自身队列。为了避免极端情况下,某一个线程的两队列中任务过于多,而空闲线程又无事可做。加入了空闲队列和任务偷取,提交任务的时候不仅唤醒自身,还会唤醒一个空闲线程,让空闲线程尝试取偷取高负载的线程任务。
正常情况,提交任务是会平均的分配给几个线程队列,目前我能想到的是同时初始化很多线程,线程中提交任务,提交完之后关闭。这样确实有可能导致任务积压到一个线程里面(不过无需担心可以有任务偷取缓解)。
如果错误欢迎斧正

头文件


//
// Created by Administrator on 2025/8/22.
//

#ifndef THREADPOOL_H
#define THREADPOOL_H
#ifndef MAXTHREADNUM
#define MAXTHREADNUM 64
#endif

// 任务函数类型
typedef void *(*task_func_t)(void *);

// 前向声明
typedef struct thread_pool thread_pool_t;

// 任务结构
typedef struct {
   
   
    task_func_t func;
    void *arg;
} task_t;

// 本地任务队列(双端队列)
typedef struct {
   
   
    task_t *queue;
    int capacity;
    int head;   // 从 head 取任务(本地线程用)
    int tail;   // 从 tail 放任务(本地线程用)
    pthread_mutex_t lock;     // 窃取时用
    pthread_cond_t  notify;   // 窃取通知
} local_queue_t;

// 线程池
struct thread_pool {
   
   
    local_queue_t *queues;    // 每个线程的本地队列
    int num_workers;
    pthread_t *threads;
    int shutdown;

    // 空闲线程管理
    int idle_workers[MAXTHREADNUM];     // 存储空闲 worker 的索引(最大支持 MAXTHREADNUM 个线程)
    int idle_count;           // 当前空闲线程数量
    pthread_mutex_t idle_lock; // 保护 idle_workers 和 idle_count
};

typedef struct {
   
   
    int index;
    thread_pool_t * pool;
}thread_pool_c;

// 初始化线程池
thread_pool_t* thread_pool_init(int num_workers);
// 提交任务放入某个线程的本地队列
int thread_pool_submit(thread_pool_t *pool, task_func_t func, void *arg);
// 销毁线程池
void thread_pool_destroy(thread_pool_t *pool);
#endif //THREADPOOL_H

源文件

//
// Created by Administrator on 2025/8/22.
//
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include "threadpool.h"

// === 双端队列操作 ===

// 队列是否为空
static int queue_empty(local_queue_t *q) {
   
   
    return q->head == q->tail;
}

// 队列是否满
static int queue_full(local_queue_t *q) {
   
   
    return (q->tail + 1) % q->capacity == q->head;
}

// 非线程安全,仅用于本线程查询自己的队列(由本线程调用)
int local_queue_size_fast(local_queue_t *q) {
   
   
    if (!q) return -1;
    int size = (q->tail - q->head + q->capacity) % q->capacity;
    return size;
}

// 向本地队列尾部添加任务(由本线程调用)
static int queue_push_tail(local_queue_t *q, task_t task) {
   
   
    if (queue_full(q)) return -1;
    q->queue[q-><
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值