POSIX标准下的线程池的简单实现

POSIX标准下的线程池的简单实现

一 条件变量操作

函数名功能函数原型
pthread_cond_init条件变量的初始化int pthread_cond_init(pthread_cond_t*cv,const pthread_condattr_t *cattr);
pthread_cond_wait等待(阻塞)在条件变量上int pthread_cond_wait(pthread_cond_t *cv,pthread_mutex_t *mutex);
pthread_cond_timedwait阻塞直到指定时间int pthread_cond_timedwait(pthread_cond_t cv,pthread_mutex_t *mp, const structtimespec abstime);
pthread_cond_signal解除在条件变量上的阻塞int pthread_cond_signal(pthread_cond_t *cv);
pthread_cond_broadcast释放阻塞的所有线程int pthread_cond_broadcast(pthread_cond_t *cv);
pthread_cond_destroy释放条件变量int pthread_cond_destroy(pthread_cond_t *cv);

函数详细解析请参考http://blog.csdn.net/ffilman/article/details/4871920

注:pthread_cond_broadcast 只会对当前所有阻塞的条件变量进行广播。而为未阻塞的条件变量不会受任何影响。

二 互斥锁的操作

函数名功能函数原型
pthread_mutex_init初始化互斥锁int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
pthread_mutex_lock()加锁,如果尝试锁定已经被上锁的互斥锁则阻塞至可用为止int pthread_mutex_lock(pthread_mutex_t *mutex);
pthread_mutex_trylock()加锁,非阻塞版的pthread_mutex_lockint pthread_mutex_trylock( pthread_mutex_t *mutex );
pthread_mutex_unlock()解锁int pthread_mutex_unlock(pthread_mutex_t *mutex);
pthread_mutex_destroy()销毁互斥锁int pthread_mutex_destroy(pthread_mutex_t *mutex);

三 线程函数的操作

函数名功能函数原型
pthread_create()线程创建函数int pthread_create(pthread_t restrict tid,const pthread_attr_t *restrict attr,void (start_rtn)(void ),void *restrict arg);
pthread_self()获取线程自身idpthread_t pthread_self(void);
pthread_join()等待一个线程结束int pthread_join(pthread_t thread, void **retval);
pthread_kill()给一个线程发送信号int pthread_kill(pthread_t thread, int sig);
pthread_exit()线程退出函数void pthread_exit(void* retval);

四 线程池的实现

线程池的适用范围:适用于多CPU大量任务简单执行时间段的情况
本线程池通过互斥量和条件变量的组合使用来对生产者消费者
模型进行控制,通过链表实现任务队列功能,满足任务的顺序执行。线程
执行任务的函数为测试代码main.c中的void *mytask(void *arg){};需要执行其他任务时,可以重写该函数。

以下是其的简单实现:
condition.h

#ifndef __CONDITION_H_
#define __CONDITION_H_

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

typedef struct condition
{
    pthread_mutex_t pmutex;
    pthread_cond_t pcond;
} condition_t;

int condition_init(condition_t *cond);
int condition_lock(condition_t *cond);
int condition_unlock(condition_t *cond);
int condition_wait(condition_t *cond);
int condition_timedwait(condition_t *cond,const struct timespec *abstime);
int condition_signal(condition_t *cond);
int condition_broadcast(condition_t *cond);
int condition_destroy(condition_t *cond);
#endif

condition.c

#include "condition.h"

int condition_init(condition_t *cond)
{
        int status;
        if(status = pthread_mutex_init(&cond->pmutex,NULL))
        {
            return status;
        }

        if(status = pthread_cond_init(&cond->pcond,NULL))
        {
            return status;
        }

        return 0;
}

int condition_lock(condition_t *cond)
{
        return pthread_mutex_lock(&cond->pmutex);
}

int condition_unlock(condition_t *cond)
{
        return pthread_mutex_unlock(&cond->pmutex); 
}

int condition_wait(condition_t *cond)
{
        return pthread_cond_wait(&cond->pcond,&cond->pmutex);
}

int condition_timedwait(condition_t *cond,const struct timespec *abstime)
{
        return pthread_cond_timedwait(&cond->pcond,&cond->pmutex,abstime);
}

int condition_signal(condition_t *cond)
{
        return pthread_cond_signal(&cond->pcond);
}

int condition_broadcast(condition_t *cond)
{
        return pthread_cond_broadcast(&cond->pcond);
}

int condition_destroy(condition_t *cond)
{
        int status;
        if(status = pthread_mutex_destroy(&cond->pmutex));
        {
            return status;
        }

        if(status = pthread_cond_destroy(&cond->pcond));
        {
            return status;
        }

        return 0;
}

pthread.h

# ifndef __PTHREAD_H
# define __PTHREAD_H
#include "condition.h"
//任务结构体,将任务放入队列由线程池中的线程来执行
typedef struct task
{
    void *(*run)(void *arg);    //任务回调函数
    void *arg;                  //回调函数参数
    struct task *next;          
} task_t;

//线程池结构体
typedef struct threadpool
{
    condition_t ready;          //任务准备就绪或者线程池销毁通知
    task_t  *first;             //任务队列头指针
    task_t  *last;              //任务队列尾指针
    int     counter;            //线程池中当前线程数
    int     idle;               //线程池中当前正在等待任务(空闲)的线程数
    int     max_threads;        //线程池中最大允许的线程数
    int     quit;               //销毁线程池的时候置1
} threadpool_t;

//初始化线程池
void threadpool_init(threadpool_t *pool,int threads);
//往线程池中添加任务
void threadpool_add_task(threadpool_t *pool,void *(*run)(void *arg),void *arg);
//销毁线程池
void threadpool_destroy(threadpool_t *pool);
#endif

pthread.c

# include <string.h>
# include <errno.h>
# include <time.h> 
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include "pthread.h"
//创建线程给的函数,线程处理函数
void *thread_routine(void *arg)
{
    struct timespec abstime;
    int timeout=0; 
    printf("thread 0x%0x is starting.\n",(int)pthread_self());
    threadpool_t *pool=(threadpool_t *) arg;
    while(1)
    {
        timeout = 0;
        condition_lock(&pool->ready);
        pool->idle++;
        //等待对列有任务到来或者线程销毁通知
        while(pool->first == NULL && !pool->quit)
        {
            printf("thread 0x%0x is waiting.\n",(int)pthread_self());
            /*等待超时,任务队列没有任务*/
            //condition_wait(&pool->ready);
            clock_gettime(CLOCK_REALTIME,&abstime);
            abstime.tv_sec += 2;
           int status = condition_timedwait(&pool->ready,&abstime);
            if (status == ETIMEDOUT)
            {
                printf("thread 0x%0x is wait time out.\n",(int)pthread_self());
                timeout=1;
                break;
            }
        }
        //等待到条件,处于工作状态
        pool->idle--;

        if(pool->first !=NULL)
        {
            //从头取出任务
            task_t *t=pool->first;
            pool->first=t->next;
            //执行任务需要一定的时间,所以要解锁,以便生产者进程能够往队列中
            //添加任务,其他消费者线程能够进入等待任务
            condition_unlock(&pool->ready);
            t->run(t->arg);
            free(t);
            condition_lock(&pool->ready);
        }
        //如果等待到线程池销毁通知,并且任务队列为空
        if(pool->quit && pool->first == NULL)
        {
            pool->counter--;
            /*如果当前线程为0*/
            if(pool->counter == 0)
            {
                condition_signal(&pool->ready);
            }
            condition_unlock(&pool->ready);
            break;
        }

        //超时
        if(timeout && pool->first == NULL)
        {
            pool->counter--;
            condition_unlock(&pool->ready);
            break;
        }
        condition_unlock(&pool->ready);
    }
    printf("thread 0x%0x is exiting.\n",(int)pthread_self());
    return NULL;
}

//初始化线程池
void threadpool_init(threadpool_t *pool,int threads)
{
    condition_init(&pool->ready);
    pool->first=NULL;
    pool->last=NULL;
    pool->counter=0;
    pool->idle=0;
    pool->max_threads=threads;
    pool->quit=0;
}
//往线程池中添加任务
void threadpool_add_task(threadpool_t *pool,void *(*run)(void *arg),void *arg)
{
    /*生成一个新任务*/
    task_t *newtask = (task_t*)malloc(sizeof(task_t));
    newtask->run=run;
    newtask->arg=arg;
    newtask->next=NULL;

    condition_lock(&pool->ready);
    /*将任务添加到任务队列*/
    if(pool->first == NULL)
    {
        pool->first=newtask;
    } else{
        pool->last->next=newtask;
    }
    pool->last=newtask;

    /*,如果有空闲线程,唤醒线程*/
    if(pool->idle>0)
    {
        condition_signal(&pool->ready);
    }else if(pool->counter < pool->max_threads)
    {
        //没有等待线程,并且当前线程数不超过最大线程数,则创建一个新线程
        pthread_t tid;
        pthread_create(&tid,NULL,thread_routine,pool);
        pool->counter++;
    }
    condition_unlock(&pool->ready);
}
//销毁线程池
void threadpool_destroy(threadpool_t *pool)
{
    if(pool->quit)
    {
        return;
    }
    condition_lock(&pool->ready);
    pool->quit = 1;
    if(pool->counter > 0)
    {
        if(pool->idle > 0)
        {
            //广播
            condition_broadcast(&pool->ready);
        }
            //处于执行任务状态的线程不会收到广播,线程池需要等待执行
            //任务状态的线程全部退出
        while(pool->counter > 0)
        {
            condition_wait(&pool->ready);
        }
    }
    condition_unlock(&pool->ready);
    condition_destroy(&pool->ready);
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include "pthread.h"

void *mytask(void *arg)
{
    printf("thread 0x%0x is working on task %d.\n",(int)pthread_self(),*(int*)arg);
    sleep(1);
    free(arg);
    return NULL;
}

int main()
{
    threadpool_t pool;
    threadpool_init(&pool,3);

    int i;
    for(i=0;i<10;i++)
    {
        int *arg = (int*)malloc(sizeof(int));
        *arg = i;
        threadpool_add_task(&pool,mytask,arg);
    }

    threadpool_destroy(&pool);
    return 0;
}

Makefile

pool:main.o pthread.o condition.o
    gcc -Wall -g  condition.o pthread.o main.o -o pool -lpthread -lrt
main.o:main.c
    gcc -Wall -g -c main.c
pthread.o:pthread.c
    gcc -Wall -g -c pthread.c
condition.o:condition.c
    gcc -Wall -g -c condition.c
clean :
    rm condition.o pthread.o main.o
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值