linux系统编程之posix线程池

源码

debug.h

#ifndef DEBUG_H

        #define DEBUG_H

        #include <stdio.h>

        #define DEBUG_MSG(msg) { \
                fprintf(stdout,"[file:%s,function:%s,line:%d],%s\n",__FILE__,__FUNCTION__,__LINE__,msg); \
                fflush(stdout); \
                }
#endif

thread_pool.h

#ifndef THREAD_POOL_H

    #define THREAD_POOL_H

    #define THREAD_POOL_TASK_NUM_MAX 256
    #define THREAD_POOL_THREAD_NUM_MAX 8

    #include <pthread.h>
    typedef pthread_t thread_pool_thread_id_t;
    typedef pthread_mutex_t thread_pool_mutex_t;
    typedef pthread_cond_t thread_pool_cond_t;

    typedef enum
    {   
        STOPPED = 0,
        SUSPEND = 1,
        RUNNING = 2,
    }thread_pool_status_t;

    typedef struct 
    {
        void *(*function)(void *arg);
        void *arg;
    }thread_pool_task_t;

    typedef struct 
    {
        thread_pool_status_t status;
        thread_pool_mutex_t mutex;
        thread_pool_cond_t cond;
        void *(*threadCommonFun)(void *arg);
        thread_pool_thread_id_t *threadIdArray;
        thread_pool_task_t *taskArray;
        int taskNum;
        int taskIndex;
    }thread_pool_t;

    typedef enum
    {
        ERR_NONE = 0,
        ERR_ARG_INVALID = 1,
        ERR_TASK_FULL = 2,
        ERR_FUNCTION_CALL = 3,
    }thread_pool_error_t;

    thread_pool_t *CreatThreadPool(void);
    thread_pool_error_t InitThreadPool(thread_pool_t *pThreadPool);
    thread_pool_error_t ThreadPoolAddTask(thread_pool_t *pThreadPool,thread_pool_task_t *pTask);
    thread_pool_error_t ThreadPoolDestroy(thread_pool_t *pThreadPool);
    void *threadCommonFunction(void *arg);

#endif


thread_pool.c

#include <stdio.h>
#include <stdlib.h>

#include "thread_pool.h"
#include "debug.h"

thread_pool_t *CreatThreadPool(void)
{
    thread_pool_t *pThreadPool;
    pThreadPool = (thread_pool_t *)malloc(sizeof(thread_pool_t));
    if (pThreadPool == NULL)
    {
        DEBUG_MSG("malloc error");
        return(NULL);
    }
    return(pThreadPool);
}

thread_pool_error_t InitThreadPool(thread_pool_t *pThreadPool)
{
    if (pThreadPool == NULL)
    {
        DEBUG_MSG("pThreadPool NULL");
        return(ERR_ARG_INVALID);
    }

    pThreadPool->status = SUSPEND;

    int intRet = -1;
    intRet = pthread_mutex_init(&pThreadPool->mutex,NULL);
    if (intRet != 0)
    {
        DEBUG_MSG("pthread_mutex_init error");
        (void)ThreadPoolDestroy(pThreadPool);
        return(ERR_FUNCTION_CALL);
    }

    intRet = pthread_cond_init(&pThreadPool->cond,NULL);
    if (intRet != 0)
    {
        DEBUG_MSG("pthread_cond_init error");
        (void)ThreadPoolDestroy(pThreadPool);
        return(ERR_FUNCTION_CALL);
    }

    pThreadPool->threadCommonFun = threadCommonFunction;

    thread_pool_thread_id_t *pThreadPoolThreadID;
    pThreadPoolThreadID = (thread_pool_thread_id_t*)malloc(sizeof(thread_pool_thread_id_t) * THREAD_POOL_THREAD_NUM_MAX);
    if (pThreadPoolThreadID == NULL)
    {
        DEBUG_MSG("malloc error");
        (void)ThreadPoolDestroy(pThreadPool);
        return(ERR_FUNCTION_CALL);
    }
    pThreadPool->threadIdArray = pThreadPoolThreadID;

    intRet = pthread_mutex_lock(&pThreadPool->mutex);
    if (intRet != 0)
    {
        DEBUG_MSG("pthread_mutex_lock error");
        (void)ThreadPoolDestroy(pThreadPool);
        return(ERR_FUNCTION_CALL);
    }

    for (int i = 0; i < THREAD_POOL_THREAD_NUM_MAX; i ++)
    {
        intRet = pthread_create(&pThreadPool->threadIdArray[i],NULL,pThreadPool->threadCommonFun,pThreadPool);
        if (intRet != 0)
        {
            DEBUG_MSG("malloc error");
            (void)ThreadPoolDestroy(pThreadPool);
            return(ERR_FUNCTION_CALL);
        }
    }

    intRet = pthread_mutex_unlock(&pThreadPool->mutex);
    if (intRet != 0)
    {
        DEBUG_MSG("pthread_mutex_unlock error");
        (void)ThreadPoolDestroy(pThreadPool);
        return(ERR_FUNCTION_CALL);
    }

    thread_pool_task_t *pThreadPoolTask;
    pThreadPoolTask = (thread_pool_task_t*)malloc(sizeof(thread_pool_task_t) * THREAD_POOL_THREAD_NUM_MAX);
    if (pThreadPoolTask == NULL)
    {
        DEBUG_MSG("malloc error");
        (void)ThreadPoolDestroy(pThreadPool);
        return(ERR_FUNCTION_CALL);
    }
    pThreadPool->taskArray = pThreadPoolTask;

    pThreadPool->taskNum = 0;
    pThreadPool->taskIndex = 0;

    return(ERR_NONE);
}

thread_pool_error_t ThreadPoolAddTask(thread_pool_t *pThreadPool,thread_pool_task_t *pTask)
{
    if (pThreadPool == NULL)
    {
        DEBUG_MSG("pThreadPool NULL");
        return(ERR_ARG_INVALID);
    }
    if (pTask == NULL)
    {
        DEBUG_MSG("pTask NULL");
        return(ERR_ARG_INVALID);
    }
    if (pThreadPool->taskNum >= THREAD_POOL_TASK_NUM_MAX)
    {
        DEBUG_MSG("pTask NULL");
        return(ERR_TASK_FULL);
    }

    pThreadPool->status = SUSPEND;

    pThreadPool->taskArray[pThreadPool->taskNum].function = pTask->function;
    pThreadPool->taskArray[pThreadPool->taskNum].arg = pTask->arg;

    pThreadPool->taskNum ++;

    pThreadPool->status = RUNNING;

    int intRet = -1;
    intRet = pthread_cond_signal(&pThreadPool->cond);
    if (intRet != 0)
    {
        DEBUG_MSG("pthread_cond_signal error");
        (void)ThreadPoolDestroy(pThreadPool);
        return(ERR_FUNCTION_CALL);
    }

    return(ERR_NONE);
}

thread_pool_error_t ThreadPoolDestroy(thread_pool_t *pThreadPool)
{
    if (pThreadPool == NULL)
    {
        DEBUG_MSG("pThreadPool NULL");
        return(ERR_ARG_INVALID);
    }

    pThreadPool->status = STOPPED;

    int intRet = -1;
    // 惊群
    intRet = pthread_cond_broadcast(&pThreadPool->cond);
    if (intRet != 0)
    {
        DEBUG_MSG("pthread_cond_broadcast error");
        return(ERR_FUNCTION_CALL);
    }
    // 收尸
    for (int i = 0; i < THREAD_POOL_THREAD_NUM_MAX; i ++)
    {
        intRet = pthread_join(pThreadPool->threadIdArray[i],NULL);
        if (intRet != 0)
        {
            DEBUG_MSG("pthread_join error");
            return(ERR_FUNCTION_CALL);
        }
    }
    if (pThreadPool->threadIdArray != NULL)
    {
        free(pThreadPool->threadIdArray);
    }
    if (pThreadPool->taskArray != NULL)
    {
        free(pThreadPool->taskArray);
    }
    free(pThreadPool);
    return(ERR_NONE);
}

void *threadCommonFunction(void *arg)
{
    thread_pool_t *pThreadPool = (thread_pool_t *)arg;
    thread_pool_task_t *pTask = NULL;
    int intRet = -1;
    for (;;)
    {
        // fprintf(stdout,"tid:%ld before pthread_mutex_lock\n",pthread_self());
        intRet = pthread_mutex_lock(&pThreadPool->mutex);
        if (intRet != 0)
        {
            DEBUG_MSG("pthread_mutex_lock error");
            pthread_exit(NULL);
        }
        // fprintf(stdout,"tid:%ld after pthread_mutex_lock\n",pthread_self());
        for (;;)
        {
            if (pThreadPool->status == STOPPED)
            {
                // fprintf(stdout,"tid:%ld located STOPPED\n",pthread_self());
                intRet = pthread_mutex_unlock(&pThreadPool->mutex);
                if (intRet != 0)
                {
                    DEBUG_MSG("pthread_mutex_unlock error");
                    pthread_exit(NULL);
                }
                pthread_exit(NULL);
            }
            else if (pThreadPool->status == SUSPEND)
            {
                // fprintf(stdout,"tid:%ld located SUSPEND\n",pthread_self());
                intRet = pthread_cond_wait(&pThreadPool->cond,&pThreadPool->mutex);
                if (intRet != 0)
                {
                    DEBUG_MSG("pthread_cond_wait error");
                    intRet = pthread_mutex_unlock(&pThreadPool->mutex);
                    if (intRet != 0)
                    {
                        DEBUG_MSG("pthread_mutex_unlock error");
                        pthread_exit(NULL);
                    }
                    pthread_exit(NULL);
                }
                // fprintf(stdout,"tid:%ld located SUSPEND && if taskNum\n",pthread_self());
                if (pThreadPool->taskNum < 1)
                {
                    continue;
                }
                else 
                {
                    // fprintf(stdout,"tid:%ld located SUSPEND && break\n",pthread_self());
                    break;
                }
            }
            else if (pThreadPool->status == RUNNING)
            {
                // fprintf(stdout,"tid:%ld located RUNNING then break\n",pthread_self());
                break;
            }
        }

        if (pThreadPool->taskIndex == pThreadPool->taskNum)
        {
            pThreadPool->taskIndex = 0;
        }
        // fprintf(stdout,"tid:%ld before get task\n",pthread_self());
        pTask = &pThreadPool->taskArray[pThreadPool->taskIndex];
        // fprintf(stdout,"tid:%ld after get task\n",pthread_self());

        pThreadPool->taskIndex ++;

        // fprintf(stdout,"tid:%ld before pthread_mutex_unlock\n",pthread_self());
        intRet = pthread_mutex_unlock(&pThreadPool->mutex);
        if (intRet != 0)
        {
            DEBUG_MSG("pthread_mutex_unlock error");
            pthread_exit(NULL);
        }
        // fprintf(stdout,"tid:%ld after pthread_mutex_unlock\n",pthread_self());

        (pTask->function)(pTask->arg);
    }
}

main.c

#include <stdio.h>
#include <stdlib.h>

#include "thread_pool.h"
#include "debug.h"

#define THREAD_MSG(msg) { fprintf(stdout,"tid:%ld in %s\n",pthread_self(),msg); }

void *task1(void *arg)
{
    THREAD_MSG("task1");
}

void *task2(void *arg)
{
    THREAD_MSG("task2");
}

void *task3(void *arg)
{
    THREAD_MSG("task3");
}

void *task4(void *arg)
{
    THREAD_MSG("task4");
}

void *task5(void *arg)
{
    THREAD_MSG("task5");
}

void *task6(void *arg)
{
    THREAD_MSG("task6");
}

void *task7(void *arg)
{
    THREAD_MSG("task7");
}

void *task8(void *arg)
{
    THREAD_MSG("task8");
}

int main(int argc,char **argv)
{
    thread_pool_t *pool;
    thread_pool_error_t ret;
    
    pool = CreatThreadPool();
    if (pool == NULL)
    {
        DEBUG_MSG("CreatThreadPool error");
        exit(1);
    }
    
    ret = InitThreadPool(pool);
    if (ret != ERR_NONE)
    {
        DEBUG_MSG("CreatThreadPool error");
        exit(1);
    }
    
    thread_pool_task_t taskArr[8];
    taskArr[0].function = task1;
    taskArr[1].function = task2;
    taskArr[2].function = task3;
    taskArr[3].function = task4;
    taskArr[4].function = task5;
    taskArr[5].function = task6;
    taskArr[6].function = task7;
    taskArr[7].function = task8;
    
    for (int i = 0; i < 8; i ++)
    {
        taskArr[i].arg = NULL;
    }

    for (int i = 0; i < 8; i ++)
    {
        ret = ThreadPoolAddTask(pool,&taskArr[i]);
        if (ret != ERR_NONE)
        {
            DEBUG_MSG("ThreadPoolAddTask error");
            exit(1);
        }
    }
    
    for (;;)
    {
        ;
    }
    
    exit(0);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值