前言
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-><

最低0.47元/天 解锁文章
305

被折叠的 条评论
为什么被折叠?



