线程池C和C++语言实现

本文介绍了线程池的应用场景、原理和结构,详细讲解了如何使用C和C++实现线程池,包括任务队列、线程池使用者和工作线程的交互模型,以及线程池的管理策略。
摘要由CSDN通过智能技术生成

一、线程池介绍

1)应用场景

当并发数很多的时候,并且每个线程执行时间很短的任务,这样就会频繁创建线程,而这样的频繁创建和销毁线程会大大降低系统的执行效率。对于这种场景我们可以使用线程池来复用之前创建的线程,降低线程的频繁创建和销毁工作,达到提高执行效率的目的。

2)线程池原理

线程池使用者往线程池任务队列里面添加任务,线程池会根据任务的多少来自动创建或销毁工作线程取执行任务,即当任务数量比较多而线程池比较少处于忙不过来的状态时,线程池就会自动创建线程,而当仍务数量比较少而空闲线程比较多时,线程池就会自动销毁一部分空闲线程。其中任务队列、线程池使用者和工作线程组成一个生产者消费者模型,线程池使用者(消费者)检查队列已满就阻塞,否则就向任务队列添加任务并通知工作线程(消费者)取任务执行,而工作线程(消费者)取任务之后也会向线程池使用者(生产者)发送通知解阻塞。

3)线程池结构

线程池由任务队列工作线程管理线程三部分组成,他们的所用分别如下。

  • 任务队列
    • 负责保存要执行的任务(一般每个任务就是一个回调函数);
    • 线程池使用者(生产者)往任务队列里面添加任务,并通知工作线程(消费者)取任务执行;
    • 工作线程(消费者)从任务队列里面获取到任务后,需要把该任务从队列中删除;
  • 工作线程
    • 负责执行任务队列里面的任务;
    • 当任务队列没有任务时,工作线程便自动睡眠防止占用CPU资源;
    • 当由任务时唤醒工作线程,从队列中取任务执行(从队列中取出任务后,如果生产者此时阻塞的话可以通知生产者解阻塞);
  • 管理线程
    • 负责控制工作线程的数量;
    • 当空闲的工作线程数量比较多时,就销毁一部分线程;
    • 当队列任务比较多而工作线程比较少时,新创建一部分线程;

线程池结构图

二、程序实现

1)C语言实现

threadPool.h

#ifndef _THREAD_POOL_
#define _THREAD_POOL_

typedef struct ThreadPool ThreadPool;

// 创建并初始化线程池
ThreadPool* threadPoolCreate(int queueSize, int minNum, int maxNum);

// 销毁线程池
void threadPoolDestory(ThreadPool* pool);

// 往线程池添加任务
int threadPoolAdd(ThreadPool* pool, void (*handler)(void* arg), void* arg);

// 获取线程池当前工作线程数
int threadPoolWorkNum(ThreadPool* pool);

// 获取线程池当前存活线程数
int threadPoolLiveNum(ThreadPool* pool);

#endif // _THREAD_POOL_

threadPool.c

#include "threadPool.h"
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <error.h>
#include <string.h>
#include <unistd.h>

#define CHAGNUM 4

void* worker(void *arg);
void* manager(void *arg);
void threadExit(ThreadPool* pool);

typedef struct Task {
   
    void (*handler)(void* arg);
    void* arg;
}Task;

struct ThreadPool {
   
    Task* taskQ;
    int qCapacity;
    int qSize;
    int qFront;
    int qBack;

    pthread_t manageID;
    pthread_t* workIDs;
    int maxNum;			// 最大线程数量
    int minNum;			// 最小线程数量
    int workNum;		// 正在执行任务的工作线程数量
    int liveNum;        // 当前已创建的的工作线程数量
    int exitNum;        // 需要销毁退出的线程数量

    pthread_mutex_t mutexPool;
    pthread_mutex_t mutexWork; // 锁workNum变量
    pthread_cond_t hasTask;      // 任务队列是否有任务
    pthread_cond_t isFull;       // 任务队列是否已满

    int isDestory; // 线程池是否销毁
};

ThreadPool* threadPoolCreate(int queueSize, int minNum, int maxNum)
{
   
    int i, res = 0;

    // 创建线程池对象
    ThreadPool* tPool = (ThreadPool*)malloc(sizeof(struct ThreadPool));
    if (tPool == NULL) {
   
        perror("tPool malloc:");
        goto err;
    }

    // 创建任务队列
    tPool->taskQ = (Task*)malloc(sizeof(struct Task) * queueSize);
    if (tPool->taskQ == NULL) {
   
        perror("taskQ malloc:");
        goto err;
    }
    tPool->qSize = 0;
    tPool->qCapacity = queueSize;
    tPool->qFront = tPool->qBack = 0;

    // 创建存储工作线程ID的数组
    tPool->workIDs = (pthread_t*)malloc(sizeof<
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值