如何封装成模块
#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% 增加线程