Pthread - 线程池(thread pool)实现

本文详细介绍了Pthread线程池的实现,包括线程池的基本模型、结构体定义和接口实现。线程池由线程池管理器、工作线程、任务和任务队列组成,采用生产者/消费者模型。任务队列使用单向链表实现,支持动态增加工作线程和销毁线程。文中还提到了相关工程文件和运行效果。
摘要由CSDN通过智能技术生成

Pthread - 线程池(thread pool)实现

线程池简介

线程池在多线程编程中经常要用到,其基本模型仍是生产者/消费者模型,线程池一般由线程池管理器(ThreadPool),工作线程(PoolWorker),任务( Task),任务队列(TaskQueue)四部分组成,其中
线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。
这里实现的线程池的任务队列为单向链表,支持的功能有:
添加任务时,线程池中工作线程数可以动态增长到某一阈值
任务执行完毕时,可以动态销毁线程池中的线程

结构体定义说明

任务(Task)结构体定义:

typedef struct task {
    TASK_ROUTINE run; // task handler
    TASK_PARA_TYPE arg; //para for handler "run"
    struct task* next; // pointer to the next task
}task_t;

run为任务接口函数,其参数为arg,next 为指向下一任务的指针。
访问控制结构体定义:

typedef struct condition {
    pthread_mutex_t p_mutex; //mutex
    pthread_cond_t p_cond; //condition variable
}cond_t;

该结构体封装了 Mutex 和 Condition variable 用于控制任务执行。
线程池(Threadpool)结构体定义

typedef struct threadpool {
    cond_t ready; // mutex and condition variable for thread pool
    task_t *first;  // pointer to the first task in the thread pool
    task_t *last; // point to the last past task in the thread pool
    int threadcnt; // thread count at the present
    int idle; //idle thread count at the present
    int max_threads; // max threads for thread pool
    int quit; // set 1 when destroying thread pool
}threadpool_t;

该结构体封装了线程池的任务队列头尾指针,工作线程阈值,当前工作线程数目,空闲工作线程数目,以及线程退出标志。

工程文件说明

pool_util.h - 功能函数和宏定义
condition.h,condition.c - Mutex 和 Condition variable 操作封装 >threadpool.h,threadpool.c - 线程池操作封装
makefile - 编译文件

condition.h 定义:

#pragma once

#include <sys/time.h>
#include <pthread.h>

typedef struct condition {
    pthread_mutex_t p_mutex; //mutex
    pthread_cond_t p_cond; //condition variable
}cond_t;


int cond_init(cond_t* cond); //initial Mutex and Condition variable
int cond_destroy(cond_t* cond); // deallocate Mutex and Condition variable
int cond_lock(cond_t* cond); // acquire Mutex lock
int cond_unlock(cond_t* cond);  release Mutex lock
int cond_wait(cond_t* cond); // wait for a condition
int cond_timedwait(cond_t* cond, const struct timespec *tv); // wait for a condition for a specified time
int cond_signal(cond_t* cond); // send  signal to a waiting thread
int cond_broadcast(cond_t* cond); // send  signal to all waiting thread

pthreadpool.h 定义:

#pragma once

#include "condition.h"

typedef void* (*TASK_ROUTINE) (void*);
typedef void* TASK_PARA_TYPE;

typedef struct task {
    TASK_ROUTINE run; // task handler
    TASK_PARA_TYPE arg; 
下面是一个使用pthread的并行线程池实现快速排序的C程序示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #define MAX_THREADS 4 // 最大线程数 #define MAX_SIZE 100000 // 待排序数组的最大大小 int num_threads = 1; // 当前线程数 int data[MAX_SIZE]; // 待排序数组 int data_size = 0; // 待排序数组的大小 pthread_mutex_t lock; // 互斥锁 // 交换两个元素的值 void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } // 分割数组,返回中间值的下标 int partition(int left, int right) { int pivot = data[right]; int i = left - 1; for (int j = left; j < right; j++) { if (data[j] <= pivot) { i++; swap(&data[i], &data[j]); } } swap(&data[i + 1], &data[right]); return i + 1; } // 快速排序 void quick_sort(int left, int right) { if (left < right) { int mid = partition(left, right); quick_sort(left, mid - 1); quick_sort(mid + 1, right); } } // 线程池的工作线程 void *worker_thread(void *arg) { int *data_range = (int *)arg; int left = data_range[0]; int right = data_range[1]; quick_sort(left, right); pthread_mutex_lock(&lock); // 上锁 num_threads--; // 线程数减一 pthread_mutex_unlock(&lock); // 解锁 free(data_range); // 释放内存 pthread_exit(NULL); } // 创建线程池并启动工作线程 void thread_pool(int left, int right) { pthread_t threads[MAX_THREADS]; int i, j, step = (right - left + 1) / num_threads; for (i = 0, j = left; i < num_threads - 1; i++, j += step) { int *data_range = (int *)malloc(sizeof(int) * 2); data_range[0] = j; data_range[1] = j + step - 1; pthread_create(&threads[i], NULL, worker_thread, (void *)data_range); } int *data_range = (int *)malloc(sizeof(int) * 2); data_range[0] = j; data_range[1] = right; worker_thread((void *)data_range); // 最后一个线程由主线程执行 for (i = 0; i < num_threads - 1; i++) { pthread_join(threads[i], NULL); } } int main() { pthread_mutex_init(&lock, NULL); printf("请输入待排序数组的大小(不超过%d):", MAX_SIZE); scanf("%d", &data_size); printf("请输入待排序数组:"); for (int i = 0; i < data_size; i++) { scanf("%d", &data[i]); } printf("请输入线程数(不超过%d):", MAX_THREADS); scanf("%d", &num_threads); if (num_threads > MAX_THREADS) { num_threads = MAX_THREADS; } thread_pool(0, data_size - 1); quick_sort(0, data_size - 1); printf("排序结果:"); for (int i = 0; i < data_size; i++) { printf("%d ", data[i]); } printf("\n"); pthread_mutex_destroy(&lock); return 0; } ``` 该程序使用了一个线程池实现并行化的快速排序算法。首先输入待排序数组的大小和数组元素,然后输入要使用的线程数。程序将待排序数组分割为若干个区间,每个区间交由一个工作线程来进行快速排序。最后,主线程对整个数组进行一次快速排序,以确保数组的完全有序。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值