C语言 线程池 问题,线程池的实现(c语言)

/** threadpool.h */

#include

struct job {

void *(*callback_function)(void *arg);//线程回调函数

void *arg;//回调函数参数

struct job *next;

};

struct threadpool;

/*

* threadpool_init

* @thread_num: 线程池开启的线程个数

* @queue_max_num: 队列的最大job个数

* return: 成功:线程池地址 失败:NULL

*/

struct threadpool *threadpool_init(int thread_num, int queue_max_num);

/*

* threadpool_add_job

* @pool: 线程池地址

* @callback_function: 回调函数参数

* @arg: 回调函数参数

* return: 成功:0 失败:-1struct threadpool

*/

int threadpool_add_job(struct threadpool *pool, void *(*callback_function)(void *arg), void *arg);

/*

* threadpool_destroy

* @pool: 线程池地址

* return: 成功:0 失败:-1

*/

int threadpool_destroy(struct threadpool *pool);

/** threadpool.c */

#include

#include

#include

#include

#include "threadpool.h"

struct threadpool

{

int thread_num;//线程池中开启线程的个数

int queue_max_num;//队列中最大job的个数

struct job *head;//指向job的头指针

struct job *tail;//指向job的尾指针

pthread_t *pthreads;//线程池中所有线程的pthread_t

pthread_mutex_t mutex;//互斥信号量

pthread_cond_t queue_empty;//队列为空的条件变量

pthread_cond_t queue_not_empty; //队列不为空的条件变量

pthread_cond_t queue_not_full;//队列不为满的条件变量

int queue_cur_num;//队列当前的job个数

int queue_close;//队列是否已经关闭

int pool_close;//线程池是否已经关闭

};

/*

threadpool_function --(queue_not_full)--> threadpool_add_job

threadpool_add_job --(queue_not_empty)--> threadpool_function

threadpool_function --(queue_empty)--> threadpool_destroy

*/

void *threadpool_function(void *arg)

{

struct threadpool *pool = (struct threadpool*)arg;

struct job *pjob = NULL;

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));

}

if (pool->pool_close) {

pthread_mutex_unlock(&(pool->mutex));

pthread_exit(NULL);

}

pool->queue_cur_num--;

pjob = pool->head;

if (pool->queue_cur_num == 0) {

pool->head = pool->tail = NULL;

} else {

pool->head = pjob->next;

}

if (pool->queue_cur_num == 0) {

pthread_cond_signal(&(pool->queue_empty));

}

if (pool->queue_cur_num < pool->queue_max_num) {

pthread_cond_broadcast(&(pool->queue_not_full));

}

pthread_mutex_unlock(&(pool->mutex));

(*(pjob->callback_function))(pjob->arg);

free(pjob);

pjob = NULL;

}

}

int threadpool_add_job(struct threadpool *pool, void *(*callback_function)(void *arg), void *arg)

{

assert(pool != NULL);

assert(callback_function != NULL);

assert(arg != NULL);

pthread_mutex_lock(&(pool->mutex));

while ((pool->queue_cur_num == pool->queue_max_num) && !(pool->queue_close || pool->pool_close)) {

pthread_cond_wait(&(pool->queue_not_full), &(pool->mutex));

}

if (pool->queue_close || pool->pool_close) {

pthread_mutex_unlock(&(pool->mutex));

return -1;

}

struct job *pjob =(struct job*) malloc(sizeof(struct job));

if (NULL == pjob) {

pthread_mutex_unlock(&(pool->mutex));

return -1;

}

pjob->callback_function = callback_function;

pjob->arg = arg;

pjob->next = NULL;

if (pool->head == NULL) {

pool->head = pool->tail = pjob;

pthread_cond_broadcast(&(pool->queue_not_empty));

} else {

pool->tail->next = pjob;

pool->tail = pjob;

}

pool->queue_cur_num++;

pthread_mutex_unlock(&(pool->mutex));

return 0;

}

struct threadpool *threadpool_init(int thread_num, int queue_max_num)

{

struct threadpool *pool = NULL;

do {

pool = malloc(sizeof(struct threadpool));

if (NULL == pool) {

printf("failed to malloc threadpool!\n");

break;

}

pool->thread_num = thread_num;

pool->queue_max_num = queue_max_num;

pool->queue_cur_num = 0;

pool->head = NULL;

pool->tail = NULL;

if (pthread_mutex_init(&(pool->mutex), NULL)) {

printf("failed to init mutex!\n");

break;

}

if (pthread_cond_init(&(pool->queue_empty), NULL)) {

printf("failed to init queue_empty!\n");

break;

}

if (pthread_cond_init(&(pool->queue_not_empty), NULL)) {

printf("failed to init queue_not_empty!\n");

break;

}

if (pthread_cond_init(&(pool->queue_not_full), NULL)) {

printf("failed to init queue_not_full!\n");

break;

}

pool->pthreads = malloc(sizeof(pthread_t) * thread_num);

if (NULL == pool->pthreads) {

printf("failed to malloc pthreads!\n");

break;

}

pool->queue_close = 0;

pool->pool_close = 0;

int i;

for (i = 0; i < pool->thread_num; ++i) {

pthread_create(&(pool->pthreads[i]), NULL,

threadpool_function, (void *)pool);

}

return pool;

} while (0);

return NULL;

}

int threadpool_destroy(struct threadpool *pool)

{

assert(pool != NULL);

pthread_mutex_lock(&(pool->mutex));

if (pool->queue_close || pool->pool_close) {

pthread_mutex_unlock(&(pool->mutex));

return -1;

}

pool->queue_close = 1;

while (pool->queue_cur_num != 0) {

pthread_cond_wait(&(pool->queue_empty), &(pool->mutex));

}

pool->pool_close = 1;

pthread_mutex_unlock(&(pool->mutex));

pthread_cond_broadcast(&(pool->queue_not_empty));

pthread_cond_broadcast(&(pool->queue_not_full));

int i;

for (i = 0; i < pool->thread_num; ++i) {

pthread_join(pool->pthreads[i], NULL);

}

pthread_mutex_destroy(&(pool->mutex));

pthread_cond_destroy(&(pool->queue_empty));

pthread_cond_destroy(&(pool->queue_not_empty));

pthread_cond_destroy(&(pool->queue_not_full));

free(pool->pthreads);

free(pool);

return 0;

}

/** poolmain.c */

#include

#include

#include "threadpool.h"

#define JOBNUM2000

void *work(void *arg)

{

printf("threadpool callback fuction : %s.\n", (char *)arg);

free(arg);

usleep(1000 * 100);

return NULL;

}

int main(void)

{

struct threadpool *pool = threadpool_init(10, 20);

int loop = JOBNUM;

while (loop--) {

char *buf = (char *)malloc(sizeof(char) * 32);

snprintf(buf, 32, "%d", JOBNUM - loop);

threadpool_add_job(pool, work, buf);

}

threadpool_destroy(pool);

return 0;

}

pthread_cond_signal restarts one of the threads that are waiting on the condition variable  cond.

If  no  threads  are  waiting  on  cond, nothing happens. If several threads are waiting on cond,

exactly one is restarted, but it is not specified which.

pthread_cond_broadcast restarts all the threads that are waiting on the condition variable  cond.

Nothing happens if no threads are waiting on cond.

pthread_cond_wait  atomically  unlocks  the mutex (as per pthread_unlock_mutex) and waits for the

condition variable cond to be signaled. The thread execution is suspended and  does  not  consume

any  CPU  time  until the condition variable is signaled. The mutex must be locked by the calling

thread  on  entrance  to   pthread_cond_wait.   Before   returning   to   the   calling   thread,

pthread_cond_wait re-acquires mutex (as per pthread_lock_mutex).

Unlocking  the  mutex  and  suspending on the condition variable is done atomically. Thus, if all

threads always acquire the mutex before signaling the condition, this guarantees that the  condi‐

tion cannot be signaled (and thus ignored) between the time a thread locks the mutex and the time

it waits on the condition variable.

pthread_cond_wait 在进入休眠时会把互斥锁解锁,唤醒时会获取互斥锁

所以在没有add job之前,线程池里所有的线程都是cond wait的状态,等待queue_not_empty

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值