linux下线程池

本文介绍了一个线程池管理器的实现细节,包括线程池的创建、销毁及任务调度等功能。通过C语言实现了一个简易线程池,用于高效处理并发任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

thrmgr.h

#ifndef __THRMGR_H__
#define __THRMGR_H__

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

typedef 
struct work_item_tag 
{
    
struct work_item_tag *next;
    
void *data;
    
struct timeval time_queued;
}
 work_item_t;

typedef 
struct work_queue_tag 
{
    work_item_t 
*head;
    work_item_t 
*tail;
    
int item_count;
}
 work_queue_t;

typedef 
enum
{
    POOL_INVALID,
    POOL_VALID,
    POOL_EXIT,
}
 pool_state_t;

typedef 
struct threadpool_tag
{
    pthread_mutex_t pool_mutex;
    pthread_cond_t pool_cond;
    pthread_attr_t pool_attr;

    pool_state_t state;
    
int thr_max;
    
int thr_alive;
    
int thr_idle;
    
int idle_timeout;

    
void (*handler)(void *);

    work_queue_t 
*queue;
}
 threadpool_t;

threadpool_t 
*thrmgr_new(int max_threads, int idle_timeout, void (*handler)(void *));
void thrmgr_destroy(threadpool_t *threadpool);
int  thrmgr_dispatch(threadpool_t *threadpool, void *user_data);

#endif


thrmgr.c

#include 
"thrmgr.h"

#include 
<stdlib.h>
#include 
<memory.h>
#include 
<errno.h>

#define FALSE (0)
#define TRUE (1)

work_queue_t 
*work_queue_new()
{
    work_queue_t 
*work_q;

    work_q 
= (work_queue_t *) malloc(sizeof(work_queue_t));

    work_q
->head = work_q->tail = NULL;
    work_q
->item_count = 0;
    
return work_q;
}


void work_queue_add(work_queue_t *work_q, void *data)
{
    work_item_t 
*work_item;

    
if (!work_q) 
    
{
        
return;
    }

    work_item 
= (work_item_t *) malloc(sizeof(work_item_t));
    work_item
->next = NULL;
    work_item
->data = data;
    gettimeofday(
&(work_item->time_queued), NULL);

    
if (work_q->head == NULL) 
    
{
        work_q
->head = work_q->tail = work_item;
        work_q
->item_count = 1;
    }

    
else 
    
{
        work_q
->tail->next = work_item;
        work_q
->tail = work_item;
        work_q
->item_count++;
    }

    
return;
}


void *work_queue_pop(work_queue_t *work_q)
{
    work_item_t 
*work_item;
    
void *data;

    
if (!work_q || !work_q->head) 
    
{
        
return NULL;
    }


    work_item 
= work_q->head;
    data 
= work_item->data;
    work_q
->head = work_item->next;
    
if (work_q->head == NULL)
    
{
        work_q
->tail = NULL;
    }


    free(work_item);
    
return data;
}


void thrmgr_destroy(threadpool_t *threadpool)
{
    
if (!threadpool || (threadpool->state != POOL_VALID))
    
{
        
return;
    }


    
if (pthread_mutex_lock(&threadpool->pool_mutex) != 0
    
{
        
//logg("!Mutex lock failed ");
        exit(-1);
    }

    threadpool
->state = POOL_EXIT;

    
/* wait for threads to exit */
    
if (threadpool->thr_alive > 0)
    
{
        
if (pthread_cond_broadcast(&(threadpool->pool_cond)) != 0)
        
{
            pthread_mutex_unlock(
&threadpool->pool_mutex);
            
return;
        }

    }


    
while (threadpool->thr_alive > 0)
    
{
        
if (pthread_cond_wait (&threadpool->pool_cond, &threadpool->pool_mutex) != 0
        
{
            pthread_mutex_unlock(
&threadpool->pool_mutex);
            
return;
        }

    }


    
if (pthread_mutex_unlock(&threadpool->pool_mutex) != 0
    
{
        
//logg("!Mutex unlock failed ");
        exit(-1);
    }


    pthread_mutex_destroy(
&(threadpool->pool_mutex));
    pthread_cond_destroy(
&(threadpool->pool_cond));
    pthread_attr_destroy(
&(threadpool->pool_attr));
    free(threadpool);
    
return;
}


threadpool_t 
*thrmgr_new(int max_threads, int idle_timeout, void (*handler)(void *))
{
    threadpool_t 
*threadpool;

    
if (max_threads <= 0
    
{
        
return NULL;
    }


    threadpool 
= (threadpool_t *) malloc(sizeof(threadpool_t));

    threadpool
->queue = work_queue_new();
    
if (!threadpool->queue) 
    
{
        free(threadpool);
        
return NULL;
    }
 

    threadpool
->thr_max   = max_threads;
    threadpool
->thr_alive = 0;
    threadpool
->thr_idle  = 0;
    threadpool
->idle_timeout = idle_timeout;
    threadpool
->handler = handler;

    pthread_mutex_init(
&(threadpool->pool_mutex), NULL);
    
if (pthread_cond_init(&(threadpool->pool_cond), NULL) != 0
    
{
        free(threadpool);
        
return NULL;
    }


    
if (pthread_attr_init(&(threadpool->pool_attr)) != 0
    
{
        free(threadpool);
        
return NULL;
    }


    
if (pthread_attr_setdetachstate(&(threadpool->pool_attr), PTHREAD_CREATE_DETACHED) != 0
    
{
        free(threadpool);
        
return NULL;
    }

    threadpool
->state = POOL_VALID;

    
return threadpool;
}



void *thrmgr_worker(void *arg)
{
    threadpool_t 
*threadpool = (threadpool_t *) arg;
    
void *job_data;
    
int retval, must_exit = FALSE;
    
struct timespec timeout;

    
/* loop looking for work */
    
for (;;) 
    
{
        
if (pthread_mutex_lock(&(threadpool->pool_mutex)) != 0
        
{
            
/* Fatal error */
            
//logg("!Fatal: mutex lock failed ");
            exit(-2);
        }


        timeout.tv_sec 
= time(NULL) + threadpool->idle_timeout;
        timeout.tv_nsec 
= 0;
        threadpool
->thr_idle++;
        
while (((job_data=work_queue_pop(threadpool->queue)) == NULL) && (threadpool->state != POOL_EXIT))
        
{
            
// Sleep, awaiting wakeup ,
            retval = pthread_cond_timedwait(&(threadpool->pool_cond), &(threadpool->pool_mutex), &timeout);
            
if (retval == ETIMEDOUT) 
            
{
                must_exit 
= TRUE;
                
break;
            }

        }


        threadpool
->thr_idle--;
        
if (threadpool->state == POOL_EXIT) 
        
{
            must_exit 
= TRUE;
        }


        
if (pthread_mutex_unlock(&(threadpool->pool_mutex)) != 0
        
{
            
/* Fatal error */
            
//logg("!Fatal: mutex unlock failed ");
            exit(-2);
        }


        
if (job_data) 
        
{
            threadpool
->handler(job_data);
        }
 
        
else if (must_exit) 
        
{
            
break;
        }

    }


    
if (pthread_mutex_lock(&(threadpool->pool_mutex)) != 0)
    
{
        
/* Fatal error */
        
//logg("!Fatal: mutex lock failed ");
        exit(-2);
    }


    threadpool
->thr_alive--;
    
if (threadpool->thr_alive == 0
    
{
        
/* signal that all threads are finished */
        pthread_cond_broadcast(
&threadpool->pool_cond);
    }


    
if (pthread_mutex_unlock(&(threadpool->pool_mutex)) != 0
    
{
        
/* Fatal error */
        
//logg("!Fatal: mutex unlock failed ");
        exit(-2);
    }


    
return NULL;
}



int thrmgr_dispatch(threadpool_t *threadpool, void *user_data)
{
    pthread_t thr_id;

    
if (!threadpool) 
    
{
        
return FALSE;
    }


    
/* Lock the threadpool */
    
if (pthread_mutex_lock(&(threadpool->pool_mutex)) != 0
    
{
        
//logg("!Mutex lock failed ");
        return FALSE;
    }


    
if (threadpool->state != POOL_VALID) 
    
{
        
if (pthread_mutex_unlock(&(threadpool->pool_mutex)) != 0
        
{
            
//logg("!Mutex unlock failed ");
            return FALSE;
        }

        
return FALSE;
    }


    work_queue_add(threadpool
->queue, user_data);

    
//只有当目前没有线程idle且目前生成的线程数小于最大线程要求时创建新的线程
    if ((threadpool->thr_idle == 0&& (threadpool->thr_alive < threadpool->thr_max))
    
{
        
/* Start a new thread */
        
if (pthread_create(&thr_id, &(threadpool->pool_attr),thrmgr_worker, threadpool) != 0)
        
{
            
//logg("!pthread_create failed ");
        }
 
        
else 
        
{
            threadpool
->thr_alive++;
        }

    }


    
/*释放条件信号,如果有正在等待该信号的线程,则该线程运行*/
    pthread_cond_signal(
&(threadpool->pool_cond));

    
if (pthread_mutex_unlock(&(threadpool->pool_mutex)) != 0
    
{
        
//logg("!Mutex unlock failed ");
        return FALSE;
    }


    
return TRUE;
}


/*
使用方法,以一个tcp服务器为例,简单列出,

1, thrmgr_new初始话

2, while(1)

{

accept(......);

//构建输入参数

thrmgr_dispach(...);

}

thrmgr_destory(...);


int main () 

    threadpool_t *threadpool = thrmgr_new (5, 0, handle); 
    thrmgr_dispatch (threadpool, (void *)5); 
    thrmgr_dispatch (threadpool, (void *)7); 
    thrmgr_destroy (threadpool); 

*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值