关于线程池结构以及互斥锁的运行机制

/********************************************************************************
//作者:Honglizheng 原帖地址 http://www.cnblogs.com/newth/archive/2012/05/09/2492459.html
//
//线程池技术:1.创建2个结构体,一个为链表,另外
//一个为线程池基本信息的结构体。
//主要使用的技术难点为:
//1.添加函数指针到一个链表中,这个链表就存储这个函数的指针和参数;
//2.循环一次性为一个函数中创建最大的线程,
//3.然后每个线程就查看链表是否还有任务没有被处理,有没处理的就及时处理,然后释放内存
***********************************************************************************/
/********************************************************************************
//大神的解释:  
//你的这个work是局部变量,既不是static,也不是const,外面怎么能看见呢,然后你这样
//是想试用队列模型一边插入一边读取,这样有个坏处,对于锁的争用是很明显的,并发是上不去的
//,你可以试用多队列模型,或者是双缓冲多队列模型,将两个锁分开,只能帮到你这里了
**********************************************************************************/

#include <stdio.h>  
#include <stdlib.h>
#include <unistd.h>  
#include <sys/types.h>  
#include <pthread.h>  
#include <assert.h>

typedef struct thread{
	void *(*process)(void *arg);
	void *arg;
	struct thread *next;
}thread_worker;

typedef struct poll{
	//线程锁 条件变量
	pthread_mutex_t queue_lock;
	pthread_cond_t queue_ready;
	
	//链表,线程池所有任务
	thread_worker *queue_head;
	//是否销毁线程池
	int shutdown;
	pthread_t *threadid;
	//允许活动的线程数目
	int max_thread_num;
	//当前等待任务数
	int cur_queue_size;
}thread_poll;

static thread_poll *my_pool=NULL;

static void *thread_process(void *arg)
{
	thread_worker *thread_node = NULL;
	for(;;)
	{
		//循环处理链表里面包含的任务;
		pthread_mutex_lock(&my_pool->queue_lock);
		while((my_pool->queue_head&&my_pool->shutdown) == NULL)
		{
			//pthread_cond_wait会先将 mutex unlock,等到wait返回时,再把 mutex 重新 lock 住。
			//当临界资源改变后这个函数的阻塞解除
			pthread_cond_wait(&my_pool->queue_ready,&my_pool->queue_lock);
		}
		
		//线程池关闭,退出线程
		if(my_pool->shutdown){    
			pthread_mutex_unlock(&my_pool->queue_lock);
			pthread_exit(NULL);
		} 
		thread_worker *thread_node = my_pool->queue_head;
		my_pool->queue_head = my_pool->queue_head->next;
		pthread_mutex_unlock(&my_pool->queue_lock);
		thread_node->process(thread_node->arg);
		//thread_node为局部变量,所以不用考虑其他函数会修改它
		//因为每个线程有各自的线程栈,维护所有函数参数以及局部变量
		free(thread_node);   
	}
}

void *pool_init(int max_thread_num)
{
	my_pool=(thread_poll *)malloc(sizeof(thread_poll));
	//初始化锁
	pthread_mutex_init(&(my_pool->queue_lock),NULL);
	//初始化条件变量
	pthread_cond_init(&(my_pool->queue_ready),NULL);
	my_pool->queue_head = NULL;
	my_pool->shutdown = 0;
	//申请足够大的空间来保存线程句柄
	my_pool->threadid = (pthread_t*)malloc(max_thread_num*sizeof(pthread_t));
	my_pool->max_thread_num = max_thread_num;
	
	int i;
	for(i=0;i<max_thread_num;i++)
	{
		pthread_create(&(my_pool->threadid[i]) ,NULL ,thread_process ,NULL);
	}
	return my_pool;
}

 /* 销毁线程池 */
void pool_destroy()
{
	int i;
    thread_worker *member;
    
     if (my_pool->shutdown) {
        return;
     }
    my_pool->shutdown = 1;
    
    /* 通知所有正在等待的线程 */
    pthread_mutex_lock(&my_pool->queue_lock);
    pthread_cond_broadcast(&my_pool->queue_ready);
    pthread_mutex_unlock(&my_pool->queue_lock);
    for (i = 0; i < my_pool->max_thread_num; ++i) {
        pthread_join(my_pool->threadid[i], NULL);
    }
    free(my_pool->threadid);
   
    while(my_pool->queue_head) {
        member = my_pool->queue_head;
        my_pool->queue_head = my_pool->queue_head->next;
        free(member);
    }
   
    pthread_mutex_destroy(&my_pool->queue_lock);    
    pthread_cond_destroy(&my_pool->queue_ready);
   
    free(my_pool);    
  }
   
  /* 向线程池添加任务 */
 int pool_add_work(void*(*process)(void*), void *arg)
  {
    thread_worker *work, *member;
      
    if (!process){
        printf("%s:Invalid argument\n", __FUNCTION__);
        return -1;
    }
      
    work = malloc(sizeof(thread_worker));
    if (!work) {
        printf("%s:malloc failed\n", __FUNCTION__);
        return -1;
    }
    work->process = process;
    work->arg = arg;
    work->next = NULL;
  
    pthread_mutex_lock(&my_pool->queue_lock);    
    member = my_pool->queue_head;
    if (!member) {
        my_pool->queue_head = work;
    } else {
        while(member->next) {
            member = member->next;
        }
        member->next = work;
    }
      /* 通知工作者线程,有新任务添加 */
    pthread_cond_signal(&my_pool->queue_ready);
    pthread_mutex_unlock(&my_pool->queue_lock);
   
    return 0;    
}


//测试代码
void *fun(void *arg)
{
	printf("%d joker for smith",*(int*)arg);
	return NULL;
}

int main()
{
	if(pool_init(9)==NULL)
	{
		printf("create failed\n");
		exit(1);
	}
	int i;
	for(i=0;i<10;i++)
	{
		pool_add_work(fun, (void*)i);
	}
	pool_destroy();
	return 0;
}
网上看了一篇线程池代码,弄了好多天才搞懂 特把自己作得注释贴上来
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值