美文网首页
c语言实现的线程池

c语言实现的线程池

作者: Top2_头秃 | 来源:发表于2019-05-11 22:14 被阅读0次

参考网络代码后加上自己理解后的手写记录

头文件


//

// Created by zl on 2020-03-13.

//

#ifndef LINUX_THREADPOOL_H

#define LINUX_THREADPOOL_H

#include

#include

#include

#include

// 线程池运行状态的枚举值

typedef enum threadPoolFlag{RUN=0,END=1}TPF;

// 任务节点队列结构体

typedef struct _TAQ{

void* (*fun)(void*); // 指向函数的指针,函数返回void*类型指针,参数是void类型指针

    void*argv; //任务函数的参数

    struct _TAQ*next;

}TAQ;

// 线程池结构体

typedef struct _threadPool {

TPF flag;//线程池运行的标志,是否运行停止

    TAQ *taskHead;  // 任务队列头指针

    pthread_cond_t taskCond; // 任务条件变量

    pthread_mutex_t taskMutex;  // 任务互斥锁

    pthread_t *threadID; // 线程id号数组头指针

    int maxThreadNum;  //  最大线程数

    int curThreadNum; // 线程池中当前活跃的线程数

    int curTaskNum; // 当前任务数

}THP;

static THP *threadPool =NULL;

THP*createThreadPool(int threadNum);// 创建线程池

void*threadHandle(void* argv); // 处理线程函数

void addTask(void* (*fun)(void*),void* argv);  //向任务队列中添加任务

void destroyThreadPool();

#endif //LINUX_THREADPOOL_H

实体和测试文件

//
// Created by zl on 2020-03-13.
//

#include <zconf.h>
#include "threadPool.h"

//创建线程池
THP* createThreadPool(int threadNum) {
    threadPool = (THP*) malloc(sizeof(THP));

    threadPool->flag = RUN;
    threadPool->maxThreadNum = threadNum;

    pthread_mutex_init(&(threadPool->taskMutex),NULL);
    pthread_cond_init(&(threadPool->taskCond),NULL);

    threadPool->curTaskNum = 0;
    threadPool->curThreadNum = 0;
    //分配线程id数组空间
    threadPool->threadID = (pthread_t*)malloc(threadNum* sizeof(pthread_t));

    int i=0;
    for (;i<threadNum;i++) {    //创建线程
         pthread_create(&(threadPool->threadID[i]),NULL,threadHandle,NULL);
    }

    return threadPool;
}

// 增加任务到任务队列
void addTask(void* (*fun)(void*),void* argv) {
    // 新来的任务添加到任务队列头部
    TAQ *newTask = (TAQ*)malloc(sizeof(TAQ));
    newTask->fun = fun;
    newTask->argv = argv;

    // 任务队列数原子性的添加
    pthread_mutex_lock(&(threadPool->taskMutex));
    newTask->next = threadPool->taskHead;
    threadPool->taskHead = newTask;
    ++threadPool->curTaskNum;
        // 如果线程池中还有线程,就唤醒其中一个线程去执行任务
    if (threadPool->curThreadNum < threadPool->maxThreadNum) {
        pthread_cond_signal(&(threadPool->taskCond));
    }
    pthread_mutex_unlock(&(threadPool->taskMutex));
}

// 线程处理函数
void* threadHandle(void* argv) {
    while (threadPool->flag==RUN) {
        pthread_mutex_lock(&(threadPool->taskMutex));
        while (threadPool->flag == RUN && threadPool->curTaskNum == 0) { //没有任务等待添加任务
            pthread_cond_wait(&(threadPool->taskCond),&(threadPool->taskMutex));

        }
        // 执行任务队列中的任务
        if (threadPool->flag == RUN) {
            TAQ *p = threadPool->taskHead;  //领取任务
            threadPool->taskHead = threadPool->taskHead->next;
            --threadPool->curTaskNum; //任务数减1
            ++threadPool->curThreadNum;//活跃线程数+1
            pthread_mutex_unlock(&(threadPool->taskMutex));

            //执行任务
            (*(p->fun))(p->argv);
            free(p);
            p = NULL;
            --threadPool->curThreadNum;
        } else if(threadPool->flag == END) {    //销毁线程池
            --threadPool->maxThreadNum;
            pthread_mutex_unlock(&(threadPool->taskMutex));
            pthread_detach(pthread_self());
            pthread_exit(NULL);
        }
    }
}
//销毁线程池
void destroyThreadPool() {
    if (threadPool->flag == RUN) {
        threadPool->flag = END;
        pthread_cond_broadcast(&(threadPool->taskCond));
        TAQ *p = threadPool->taskHead;
        while (p) {
            --threadPool->curTaskNum;
            threadPool->taskHead = threadPool->taskHead->next;
            free(p);
            p = threadPool->taskHead;
        }
    }
}

void* testFun(void* argv) {
    int *p= (int*)argv;
    printf("线程号%lu:开始执行函数。argv=%d\n",pthread_self(),*p);
    sleep(1);
    printf("线程号%lu:函数执行完毕!argv=%d\n",pthread_self(),*p);
    return NULL;
}

int main() {

    THP *thp=createThreadPool(3);
    int i=0;
    for(;i<20;++i)
    {
        addTask(testFun,(void*)(&i));
        sleep(1);
    }
    while(thp->curTaskNum!=0);
    printf("任务执行完毕\n");
    destroyThreadPool();
    return 0;
}
测试结果 测试结果

可见一直是创建的三个线程在处理任务

相关文章

  • C语言实现线程池

    什么时候需要创建线程池呢?简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和...

  • c语言实现的线程池

    参考网络代码后加上自己理解后的手写记录 头文件 实体和测试文件 测试结果 可见一直是创建的三个线程在处理任务

  • 如何设计一个线程池?

    为什么需要线程池 如何设计一个线程池 用C++11实现一个线程池 为什么需要线程池 线程的频繁创建和销毁,不仅会消...

  • Java ThreadPoolExecutor详解

    ThreadPoolExecutor是Java语言对于线程池的实现。池化技术是一种复用资源,减少开销的技术。线程是...

  • 深入解析Java ThreadPoolExecutor

    ThreadPoolExecutor是Java语言对于线程池的实现。池化技术是一种复用资源,减少开销的技术。线程是...

  • Callable实现原理

    Callable实现原理 Callable的实现类只能配合线程池执行 在线程池中有一个submit方法,可以提交C...

  • 线程池的原理与C语言实现

    网络数据的处理流程: 1. 检测IO事件是否就绪(可读可写) epoll 等多路复用 2.对IO进行读写 ...

  • 线程以及java线程池实现分享

    线程以及java线程池实现分享 线程简介 JDK线程池的工作原理 JDK线程池的实现细节 1.线程简介-由来 1....

  • java多线程面试题

    实现多线程的方法 1.实现Thread接口 2.实现Runnable接口创建线程 3.实现 线程池 创建线程池的代...

  • C++ 实现线程池

    c++实现一个线程池,首先需要有两个数据结构,一个是线程池,一个是任务队列。为了每个线程线程安全的从任务队列里面拿...

网友评论

      本文标题:c语言实现的线程池

      本文链接:https://www.haomeiwen.com/subject/msgfaqtx.html