用c语言实现一个动态线程池
时间: 2023-11-14 15:42:20 浏览: 51
下面是一个用 C 语言实现的简单动态线程池的示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct {
void (*task_func)(void*); // 任务函数指针
void* task_arg; // 任务参数
} Task;
typedef struct {
Task* tasks; // 任务数组
int capacity; // 任务数组容量
int size; // 当前任务数量
int front; // 队列头索引
int rear; // 队列尾索引
pthread_mutex_t lock; // 互斥锁
pthread_cond_t not_empty; // 非空条件变量
pthread_cond_t not_full; // 非满条件变量
} ThreadPool;
void task_queue_init(ThreadPool* pool, int capacity) {
pool->tasks = (Task*)malloc(sizeof(Task) * capacity);
pool->capacity = capacity;
pool->size = 0;
pool->front = 0;
pool->rear = 0;
pthread_mutex_init(&pool->lock, NULL);
pthread_cond_init(&pool->not_empty, NULL);
pthread_cond_init(&pool->not_full, NULL);
}
void task_queue_destroy(ThreadPool* pool) {
free(pool->tasks);
pthread_mutex_destroy(&pool->lock);
pthread_cond_destroy(&pool->not_empty);
pthread_cond_destroy(&pool->not_full);
}
void task_queue_push(ThreadPool* pool, Task task) {
pthread_mutex_lock(&pool->lock);
while (pool->size == pool->capacity) {
pthread_cond_wait(&pool->not_full, &pool->lock);
}
pool->tasks[pool->rear] = task;
pool->rear = (pool->rear + 1) % pool->capacity;
pool->size++;
pthread_cond_signal(&pool->not_empty);
pthread_mutex_unlock(&pool->lock);
}
Task task_queue_pop(ThreadPool* pool) {
pthread_mutex_lock(&pool->lock);
while (pool->size == 0) {
pthread_cond_wait(&pool->not_empty, &pool->lock);
}
Task task = pool->tasks[pool->front];
pool->front = (pool->front + 1) % pool->capacity;
pool->size--;
pthread_cond_signal(&pool->not_full);
pthread_mutex_unlock(&pool->lock);
return task;
}
void* worker_thread(void* arg) {
ThreadPool* pool = (ThreadPool*)arg;
while (1) {
Task task = task_queue_pop(pool);
task.task_func(task.task_arg);
}
return NULL;
}
void thread_pool_init(ThreadPool* pool, int capacity, int num_workers) {
task_queue_init(pool, capacity);
pthread_t* threads = (pthread_t*)malloc(sizeof(pthread_t) * num_workers);
for (int i = 0; i < num_workers; i++) {
pthread_create(&threads[i], NULL, worker_thread, pool);
}
}
void thread_pool_destroy(ThreadPool* pool, int num_workers) {
for (int i = 0; i < num_workers; i++) {
task_queue_push(pool, (Task){NULL, NULL}); // 发送结束任务给所有工作线程
}
pthread_t* threads = (pthread_t*)malloc(sizeof(pthread_t) * num_workers);
for (int i = 0; i < num_workers; i++) {
pthread_join(threads[i], NULL);
}
task_queue_destroy(pool);
}
// 示例任务函数
void my_task(void* arg) {
printf("Hello from task\n");
}
int main() {
ThreadPool pool;
thread_pool_init(&pool, 10, 5);
for (int i = 0; i < 10; i++) {
task_queue_push(&pool, (Task){my_task, NULL});
}
thread_pool_destroy(&pool, 5);
return 0;
}
```
上述示例使用了一个循环队列来实现任务队列,通过互斥锁和条件变量来保证线程安全。`ThreadPool` 结构体表示线程池,包含了任务队列和相关的属性。`task_queue_push` 和 `task_queue_pop` 分别用于将任务放入队列和从队列中取出任务。
`worker_thread` 函数是工作线程的入口函数,它会不断从任务队列中取出任务并执行。在 `thread_pool_init` 函数中创建了指定数量的工作线程,并开始执行任务。
注意,这只是一个简单的示例实现,实际使用时可能需要更多的错误处理和线程安全的考虑。另外,该示例没有实现线程池的动态调整功能,可以根据实际需求进行扩展。