关于线程池原理及相关笔记

 

 

 

 

 

 

 

 

如何封装成模块

 

 

 

 

 


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <pthread.h>


#define LL_ADD(item,list)  do  {          \
    item->prev = NULL;                    \
    item->next = list;                    \
    if (list != NULL)   list->prev =item; \
    list = item;                          \
} while(0)                                \

#define LL_REMOVE(item,list) do{     \
   if (item->prev != NULL) item->prev->next = item->next;  \
   if (item->next != NULL) item->next->prev = item->prev;  \
   if (list == item)   list = item->next;                  \
   item->prev = item->next = NULL;                         \
} while(0)  \


typedef struct NWORKER{
    pthread_t threadid;
    int terminate;
    int flag;
    struct NMANAGER *pool;
    struct NWORKER *next;
    struct NWORKER *prev;
} nWorker;

typedef struct NJOB{

    void (*func)(void *arg);
    void *user_data;

    struct NJOB *next;
    struct NJOB *prev;

} nJob;

typedef struct NMANAGER{

    nWorker *workers;
    nJob *jobs;

    int sum_thread;    //总线程数
    int idle_thread;     //空闲数

    pthread_mutex_t *jobs_mtx;    //避免一个顾客多个技师,或是多个技师一个顾客的现像,互斥变量
    pthread_cond_t jobs_cond;    //条件变量,如果存在没有任务情况,让线程空闲,满足条件(有任务)再执行

} nManager;


typedef nManager nThreadPool;

//线程入口函数或回调函数,对外部提拱接口使用

void *nWorkerCallBack(void *arg){

    nWorker *worker = (nWorker*)arg;

    while(1){

        // 1 job != NULL 判断任务是不是为空

        pthread_mutex_lock(&worker->pool->jobs_mtx);
        while(worker->pool->jobs == NULL){
            //入这个函数是 unlock ,出这个函数为lock
            if (worker->terminate == 1) break;

            pthread_cond_wait(&worker->pool->jobs_cond,&worker->pool->jobs_mtx);

        }

        if (worker->terminate == 1) {
            pthread_mutex_unlock(&worker->pool->jobs_mtx);
            break;
        }

        // 2 ll_remove(item,jobs);   取出一个任务
        nJob *job = worker->pool->jobs;
        LL_REMOVE(job,worker->pool->jobs);
        pthread_mutex_unlock(&worker->pool->jobs_mtx);

        // 3 jobs->func(jobs);  把任务放到回调函数里
        // enter
        worker->pool->idle_thread--;

        job->func(job->user_data); //这里真正执行任务

        worker->pool->idle_thread++;

        free(job);
    }

    free(worker);

}

int nThreadPoolCreate(nThreadPool *pool,int numWorkers){

    if (pool == NULL) return -1;
    if (numWorkers<1) numWorkers = 1;
    memset(pool,0, sizeof(nThreadPool));

    pthread_mutex_t blank_mutex = PTHREAD_MUTEX_INITIALIZER;
    memcpy(&pool->jobs_mtx,&blank_mutex, sizeof(pthread_mutex_t));

    pthread_cond_t blank_cond = PTHREAD_COND_INITIALIZER;
    memcpy(&pool->jobs_cond,&blank_cond, sizeof(pthread_cond_t));

    int i = 0;
    for(i=0;i<numWorkers;i++){

        nWorker *worker = malloc(sizeof(nWorker));

        if (worker == NULL) {
            perror("malloc");
            return 1;
        }

        memset(worker,0, sizeof(nWorker));

        int ret = pthread_create(&worker->threadid,NULL,nWorkerCallBack,worker);

        if (ret) {

            perror("pthread_create");
            //free(worker);
            nWorker *w = pool->workers;
            for(w=pool->workers;w != NULL; w = w->next){
                w->terminate = 1;
            }

            return 1;
        }

        LL_ADD(worker,pool->workers);
    }

}


int nThreadPoolPushJob(nThreadPool *pool,nJob *job){

    pthread_mutex_lock(&pool->jobs_mtx);

    LL_ADD(job,pool->jobs);

    pthread_cond_signal(&pool->jobs_cond);

    pthread_mutex_unlock(&pool->jobs_mtx);

    return 0;
}

int nThreadPoolDestory(nThreadPool *pool){

    nWorker *w = pool->workers;

    for(w = pool->workers; w != NULL; w = w->next){
        w->terminate = 1;
    }

    pthread_mutex_lock(&pool->jobs_mtx);
    pthread_cond_broadcast(&pool->jobs_cond);
    pthread_mutex_unlock(&pool->jobs_mtx);

}

int main(){


    return 0;
}


//api
// int nThreadPoolCreate(nThreadPool *pool,int numWorkers)
// int nThreadPoolPushJob(nThreadPool *pool,nJob *job)
// int nThreadPoolDestory(nThreadPool *pool)

//idle_thread / sum_thread > 80% 释放线程
//idle_thread / sum_thread > 40% 增加线程

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值