简单C语言线程池的编写

本文介绍了一个简单的C语言线程池实现,包括线程池初始化、添加任务和销毁等核心功能,并通过示例展示了其工作流程。

突发奇想,想要写一个C线程池,在网上看到了类似的代码,自己按照类似的思路重新实现了一下,主要分成三个功能,线程池初始化,线程池添加任务,线程池销毁,实现方式见如下代码

mythreadpool.h

#ifndef __MYTHREADPOOL_
#define __MYTHREADPOOL_

#include<stdio.h>
#include<pthread.h>

typedef void* (*callback_t)(void* arg);

typedef struct pjob_t 
{
    callback_t callback;
    struct pjob_t* next;
    void* arg;
}pjob;

typedef struct
{
    int pool_close;
    int queue_cur_num;
    int queue_max_num;
    int thread_num;
    pjob* head;
    pjob* tail;
    pthread_mutex_t mutex;
    pthread_t *thread;
    pthread_cond_t queue_not_full;
    pthread_cond_t queue_empty;
    pthread_cond_t queue_not_empty;

}threadpool;

threadpool* threadpool_init(int thread_num,int queue_num);

void threadpool_addjob(threadpool* pool,callback_t callback,void* arg);

void threadpool_destroy(threadpool* pool);

#endif

mythreadpool.c

#include "mythreadpool.h"
#include <stdlib.h>
#include <assert.h>

static void* threadpool_function(void* arg);
threadpool* threadpool_init(int thread_num,int queue_num)
{
    threadpool* pool= (threadpool*)malloc(sizeof(threadpool));

    pool->pool_close = 0;
    pool->queue_cur_num = 0;
    pool->queue_max_num = queue_num;
    pool->thread_num = thread_num;
    pool->thread = (pthread_t*)malloc(sizeof(pthread_t)*thread_num);
    pool->head = NULL;
    pool->tail = NULL;

    pthread_mutex_init(&pool->mutex,NULL);
    pthread_cond_init(&pool->queue_not_full,NULL);
    pthread_cond_init(&pool->queue_empty,NULL);
    pthread_cond_init(&pool->queue_not_empty,NULL);
    int i = 0;

    for(i=0;i < pool->thread_num;i++)
    {
       pthread_create(&pool->thread[i],NULL,threadpool_function,(void*)pool); 
    }      
    return pool;
}

void threadpool_addjob(threadpool* pool,callback_t callback,void* arg)
{
    assert(pool != NULL);
    assert(callback != NULL);
    assert(arg != NULL);

    pthread_mutex_lock(&pool->mutex);
    while(!pool->pool_close && pool->queue_cur_num == pool->queue_max_num) 
    {
        pthread_cond_wait(&pool->queue_not_full,&pool->mutex);
        printf("add job wait\n");
    }

    pjob *job = (pjob*)malloc(sizeof(pjob));
    job->callback = callback;
    job->arg = arg;

    if(pool->head == NULL)
    {
        pool->head = pool->tail = job;
        pthread_cond_broadcast(&pool->queue_not_empty);
        printf("send queue_not_empty broadcast signal\n");
    }
    else
    {
        pool->tail->next = job; 
        pool->tail = pool->tail->next;
        job->next = NULL;
        printf("queue add job\n");
    }

    pool->queue_cur_num++;
    printf("queue_cur_num ++,num = %d\n\n",pool->queue_cur_num);
    pthread_mutex_unlock(&pool->mutex);
}

static void* threadpool_function(void* arg)
{
    threadpool* pool = (threadpool*)arg;
    printf("default thread is created\n");
    while(1) 
    {
        pthread_mutex_lock(&pool->mutex);
        while(pool->queue_cur_num == 0 && !pool->pool_close)
        {
            pthread_cond_wait(&pool->queue_not_empty,&pool->mutex);
            printf("queue_not_empty wait\n");
        }

        if(pool->pool_close)
        {
            pthread_mutex_unlock(&pool->mutex);
            printf("default thread exit\n");
            pthread_exit(NULL);
        }

        pool->queue_cur_num--;
        printf("queue_cur_num --,num = %d\n\n",pool->queue_cur_num);
        pjob* job = pool->head;

        if(pool->queue_cur_num == 0)
        {
            pool->head = pool->tail = NULL;
            pthread_cond_signal(&pool->queue_empty);
            printf("send queue_empty signal\n");
        }
        else
        {
            if(job == NULL)
            {
                printf("the job = NULL\n");
            }
            pool->head = job->next;

        }

        if(pool->queue_cur_num == pool->queue_max_num - 1)
        {
            pthread_cond_signal(&pool->queue_not_full);
            printf("send queue_not_full signal\n");
        }

        pthread_mutex_unlock(&pool->mutex);

        (job->callback)(job->arg);
        free(job);
        job = NULL;
    }
}

void threadpool_destroy(threadpool* pool)
{
    assert(pool != NULL);

    int i = 0;
    pthread_mutex_lock(&pool->mutex);
    while(pool->queue_cur_num != 0)
    {
        pthread_cond_wait(&pool->queue_empty,&pool->mutex);
        printf("threadpool destroy wait\n");
    }
    pthread_mutex_unlock(&pool->mutex);

    pool->pool_close = 1;

    for(i;i < pool->thread_num;i++)
    {
        pthread_join(pool->thread[i],NULL);
        printf("join %d times\n",i);
    }

    pthread_mutex_destroy(&pool->mutex);
    pthread_cond_destroy(&pool->queue_not_full);
    pthread_cond_destroy(&pool->queue_empty);
    pthread_cond_destroy(&pool->queue_not_empty);

    free(pool->thread);
    free(pool);
}

main.c

#include "mythreadpool.h"
#include <unistd.h>

void* thread_function(void* arg)
{
    printf("the %s thread has execued\n",(char*)arg);
    sleep(1);
}

int main()
{
    threadpool* pool = threadpool_init(10,20);
    threadpool_addjob(pool,thread_function,"1");
    threadpool_addjob(pool,thread_function,"2");
    threadpool_addjob(pool,thread_function,"3");
    threadpool_addjob(pool,thread_function,"4");
    threadpool_addjob(pool,thread_function,"5");
    threadpool_addjob(pool,thread_function,"6");
    threadpool_addjob(pool,thread_function,"7");
    threadpool_addjob(pool,thread_function,"8");
    threadpool_addjob(pool,thread_function,"9");
    threadpool_addjob(pool,thread_function,"10");
    threadpool_addjob(pool,thread_function,"11");
    threadpool_addjob(pool,thread_function,"12");
    threadpool_addjob(pool,thread_function,"13");
    threadpool_addjob(pool,thread_function,"14");
    threadpool_addjob(pool,thread_function,"15");
    threadpool_addjob(pool,thread_function,"16");
    threadpool_addjob(pool,thread_function,"17");
    threadpool_addjob(pool,thread_function,"18");
    threadpool_addjob(pool,thread_function,"19");
    threadpool_addjob(pool,thread_function,"20");
    threadpool_addjob(pool,thread_function,"21");
    threadpool_addjob(pool,thread_function,"22");
    threadpool_addjob(pool,thread_function,"23");
    threadpool_addjob(pool,thread_function,"24");
    threadpool_addjob(pool,thread_function,"25");
    threadpool_addjob(pool,thread_function,"26");
    threadpool_addjob(pool,thread_function,"27");
    threadpool_addjob(pool,thread_function,"28");
    threadpool_addjob(pool,thread_function,"29");
    threadpool_addjob(pool,thread_function,"30");
    threadpool_destroy(pool);
}

首先初始化的时候,设定开启10个线程,队列最大值为20,用来放置任务。
threadpool_function等待queue_not_empty,直到threadpool_addjob不为空则唤醒线程,然后队列的当前数量减一,判断是否为0,队列数量为0的时候代表已经没有任务了,向threadpool_destroy中发送信号,销毁线程池,如果不为0则代表取得当前任务,执行。
threadpool_addjob当队列数量等于最大数量的时候,等待threadpool_function唤醒,当第一次调用addjob的时候,唤醒所有threadpool_function进程,如果不是第一次调用的时候,将任务添加到线程池中由threadpool_function消化
运行结果如下:
send queue_not_empty broadcast signal
queue_cur_num ++,num = 1

queue add job
queue_cur_num ++,num = 2

queue add job
queue_cur_num ++,num = 3

queue add job
queue_cur_num ++,num = 4

queue add job
queue_cur_num ++,num = 5

queue add job
queue_cur_num ++,num = 6

queue add job
queue_cur_num ++,num = 7

queue add job
queue_cur_num ++,num = 8

queue add job
queue_cur_num ++,num = 9

queue add job
queue_cur_num ++,num = 10

queue add job
queue_cur_num ++,num = 11

queue add job
queue_cur_num ++,num = 12

queue add job
queue_cur_num ++,num = 13

queue add job
queue_cur_num ++,num = 14

queue add job
queue_cur_num ++,num = 15

queue add job
queue_cur_num ++,num = 16

queue add job
queue_cur_num ++,num = 17

queue add job
queue_cur_num ++,num = 18

queue add job
queue_cur_num ++,num = 19

queue add job
queue_cur_num ++,num = 20

default thread is created
queue_cur_num –,num = 19

send queue_not_full signal
the 1 thread has execued
default thread is created
add job wait
queue add job
queue_cur_num ++,num = 20

default thread is created
queue_cur_num –,num = 19

send queue_not_full signal
the 2 thread has execued
add job wait
queue add job
queue_cur_num ++,num = 20

queue_cur_num –,num = 19

send queue_not_full signal
the 3 thread has execued
default thread is created
queue_cur_num –,num = 18

the 4 thread has execued
default thread is created
add job wait
queue add job
queue_cur_num ++,num = 19

queue add job
queue_cur_num ++,num = 20

queue_cur_num –,num = 19

send queue_not_full signal
the 5 thread has execued
add job wait
queue add job
queue_cur_num ++,num = 20

default thread is created
queue_cur_num –,num = 19

send queue_not_full signal
the 6 thread has execued
add job wait
queue add job
queue_cur_num ++,num = 20

default thread is created
queue_cur_num –,num = 19

send queue_not_full signal
the 7 thread has execued
add job wait
queue add job
queue_cur_num ++,num = 20

default thread is created
queue_cur_num –,num = 19

send queue_not_full signal
the 8 thread has execued
add job wait
queue add job
queue_cur_num ++,num = 20

default thread is created
queue_cur_num –,num = 19

send queue_not_full signal
the 9 thread has execued
add job wait
queue add job
queue_cur_num ++,num = 20

default thread is created
queue_cur_num –,num = 19

send queue_not_full signal
add job wait
queue add job
queue_cur_num ++,num = 20

the 10 thread has execued
queue_cur_num –,num = 19

send queue_not_full signal
the 11 thread has execued
queue_cur_num –,num = 18

the 12 thread has execued
queue_cur_num –,num = 17

the 13 thread has execued
queue_cur_num –,num = 16

the 14 thread has execued
queue_cur_num –,num = 15

the 15 thread has execued
queue_cur_num –,num = 14

the 16 thread has execued
queue_cur_num –,num = 13

the 17 thread has execued
queue_cur_num –,num = 12

the 18 thread has execued
queue_cur_num –,num = 11

the 19 thread has execued
queue_cur_num –,num = 10

the 20 thread has execued
queue_cur_num –,num = 9

the 21 thread has execued
queue_cur_num –,num = 8

the 22 thread has execued
queue_cur_num –,num = 7

the 23 thread has execued
queue_cur_num –,num = 6

the 24 thread has execued
queue_cur_num –,num = 5

the 25 thread has execued
queue_cur_num –,num = 4

the 26 thread has execued
queue_cur_num –,num = 3

the 27 thread has execued
queue_cur_num –,num = 2

the 28 thread has execued
queue_cur_num –,num = 1

the 29 thread has execued
queue_cur_num –,num = 0

send queue_empty signal
the 30 thread has execued
threadpool destroy wait
default thread exit
default thread exit
default thread exit
default thread exit
default thread exit
default thread exit
default thread exit
default thread exit
default thread exit
default thread exit
join 0 times
join 1 times
join 2 times
join 3 times
join 4 times
join 5 times
join 6 times
join 7 times
join 8 times
join 9 times

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值