基于Linux C的线程池模型介绍

什么是线程池

线程池就是一个拥有多个线程的池子,它是多线程的一种使用方式,可以将他理解为一个执行队列,我们只需将需要完成的
工作或任务丢到线程池的工作队列中,由线程池中的线程来抢夺工作队列中的任务即可,没有抢到任务的线程处于休眠状态。

如何实现线程池

在线程池中主要可分为两大结构体,或是两个主要对象,那就是工作队列和执行队列,工作队列中保存我们待执行的任务,
执行队列就是一个一个的线程。两个结构体如下:

工作队列

struct queue_jobs
{
    struct queue_jobs *prev;
    struct queue_jobs *next;
    pthread_work_cb work_cb; 
    void *arg;
};

执行队列

struct pthread_pool
{
    int pth_num_max;
    pthread_t *tid;
    pthread_cond_t pth_cond;
    pthread_mutex_t pth_mutex;
};

其中工作队列为一个双向链表构成,结构体成员pthread_work_cb work_cb为一个函数指针,指向具体的回调函数;执行队列就是我们的线程池,主要的两个成员变量pthread_cond_t pth_cond、pthread_mutex_t pth_mutex用于操作工作队列时需要加锁,同时通知执行队列当前是否有需要执行的工作,也就是当我们向工作队列添加一个任务时,会发送一个信号来通知执行队列,执行队列收到信号后会去工作队列取出任务来执行。

完整代码如下:

pthread_pool.h

#ifndef PTHREAD_H_
#define PTHREAD_H_
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct pthread_pool pth_pool_t;
typedef void *(*pthread_work_cb)(void *);
typedef struct queue_jobs queue_jobs_t;

struct pthread_pool
{
    int pth_num_max;
    pthread_t *tid;
    pthread_cond_t pth_cond;
    pthread_mutex_t pth_mutex;
};
struct queue_jobs
{
    struct queue_jobs *prev;
    struct queue_jobs *next;
    pthread_work_cb work_cb; 
    void *arg;
};
enum{
    OK           = 0,
    POINTER_NULL = -1,
};
int pthread_pool_init(pth_pool_t **pool,int pth_num);
void pthread_pool_add_task(pthread_work_cb task,void *arg);
void pthread_pool_destroy(pth_pool_t * pth_pool);
#endif

pthread_pool.c

#include "pthread_pool.h"
pth_pool_t *pth_pool;
queue_jobs_t *q_jobs = NULL;
void *pthread_routine(void *arg);
int pthread_pool_init(pth_pool_t **pool,int pth_num)
{
    *pool = (pth_pool_t*)malloc(sizeof(pth_pool_t));

    if (*pool == NULL)
        return POINTER_NULL;
    (*pool)->pth_num_max = pth_num;
    (*pool)->tid = (pthread_t*)malloc(sizeof(pthread_t) * pth_num);
    pthread_mutex_init(&((*pool)->pth_mutex),NULL);
    pthread_cond_init(&((*pool)->pth_cond),NULL);

    for(int i=0;i<pth_num;i++)
        pthread_create(&((*pool)->tid[i]),NULL,pthread_routine,NULL);
    return OK;
}
void pthread_pool_add_task(pthread_work_cb task,void *arg)
{
    if(task == NULL)
        return;
    queue_jobs_t *job = (queue_jobs_t*)malloc(sizeof(queue_jobs_t));
    if(job == NULL)
        return ;
    job->work_cb = task;
    job->arg = arg;
    pthread_mutex_lock(&(pth_pool->pth_mutex));
    if(q_jobs == NULL)
        q_jobs = job;
    else
    {
        job->next = q_jobs;
        q_jobs->prev = job;
        q_jobs = job;
    }
    pthread_mutex_unlock(&(pth_pool->pth_mutex));
    pthread_cond_signal(&(pth_pool->pth_cond));
}
void *pthread_routine(void *arg)
{
    queue_jobs_t *job;
    pthread_detach(pthread_self());
    while(1)
    {
        #if 1
        pthread_mutex_lock(&(pth_pool->pth_mutex));
        while(q_jobs == NULL)
            pthread_cond_wait(&(pth_pool->pth_cond),&(pth_pool->pth_mutex));
        job =q_jobs;
        q_jobs = q_jobs->next;
        pthread_mutex_unlock(&(pth_pool->pth_mutex)); 
        job->work_cb(job->arg);
        free(job);
        job = NULL;
        #endif
    }
    pthread_exit(NULL);
}
void pthread_pool_destroy(pth_pool_t * pth_pool)
{
    queue_jobs_t *job;
    if(pth_pool == NULL)
        return ;
    
    pthread_mutex_destroy(&pth_pool->pth_mutex);
    pthread_cond_destroy(&pth_pool->pth_cond);
    while(q_jobs)
    {
        job = q_jobs;
        q_jobs = q_jobs->next;
        free(job);
    }
    free(pth_pool->tid);
    free(pth_pool);
}

测试main.c,这里我创建了一个线程池,里面有8个线程,同时向线程池中添加了8个任务,每个任务执行的时间不同。

#include <unistd.h>
#include <stdio.h>
#include "pthread_pool.h"
#define PTHREAD_NUM_MAX     8   
extern pth_pool_t *pth_pool;
void * pthread1_task(void *arg)
{
    for (int  i = 0; i < 3; i++)
    {
        /* code */
        printf("this is 1 thread,tid:%ld\n",pthread_self());
        sleep(1);
    }
    return (void *)0;
    
}
void * pthread2_task(void *arg)
{
    for (int i = 0; i < 4; i++)
    {
        /* code */
         printf("this is 2 thread,tid:%ld\n",pthread_self());
         sleep(1);
    }
    return (void *)0;
}
void * pthread3_task(void *arg)
{
    for (int  i = 0; i < 5; i++)
    {
        /* code */
         printf("this is 3 thread,tid:%ld\n",pthread_self());
        sleep(1);
    }
    return (void *)0;
}
void * pthread4_task(void *arg)
{
    for (int  i = 0; i < 6; i++)
    {
        /* code */
         printf("this is 4 thread,tid:%ld\n",pthread_self());
        sleep(1);
    }
    return (void *)0;
}
void * pthread5_task(void *arg)
{
    for (int  i = 0; i < 6; i++)
    {
        /* code */
         printf("this is 5 thread,tid:%ld\n",pthread_self());
        sleep(1);
    }
    return (void *)0;
}
void * pthread6_task(void *arg)
{
    for (int  i = 0; i < 6; i++)
    {
        /* code */
         printf("this is 6 thread,tid:%ld\n",pthread_self());
        sleep(1);
    }
    return (void *)0;
}
void * pthread7_task(void *arg)
{
    for (int  i = 0; i < 2; i++)
    {
        /* code */
         printf("this is 7 thread,tid:%ld\n",pthread_self());
        sleep(1);
    }
    return (void *)0;
}
void * pthread8_task(void *arg)
{
    for (int  i = 0; i < 1; i++)
    {
        /* code */
         printf("this is 8 thread,tid:%ld\n",pthread_self());
        sleep(1);
    }
    return (void *)0;![在这里插入图片描述](https://img-blog.csdnimg.cn/babbfbae42014a1cbc4585d30a24106d.png#pic_center)

}
int main()
{
    if(pthread_pool_init(&pth_pool,PTHREAD_NUM_MAX) == 0)
        printf("pthread pool init success\n");
    else
    {
        printf("pthread pool init failed\n");
        return -1;
    }
    pthread_pool_add_task(pthread1_task,NULL);
    pthread_pool_add_task(pthread2_task,NULL);
    pthread_pool_add_task(pthread3_task,NULL);
    pthread_pool_add_task(pthread4_task,NULL);
    pthread_pool_add_task(pthread5_task,NULL);
    pthread_pool_add_task(pthread6_task,NULL);
    pthread_pool_add_task(pthread7_task,NULL);
    pthread_pool_add_task(pthread8_task,NULL);
    while(1);
    return 0;
}

执行效果:
在这里插入图片描述
到此完结!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值