一个简单线程池的实现---需进一步完善
2016-03-01 20:41
357 查看
1.定义一个任务结构体,和一个线程池结构体
struct task{
void *(*p)(void*);//需要实现的函数;
void *arg;//函数所带的参数
struct task *next;
};
struct pthread_pool{
pthread_mutex_t mutex;//线程锁
pthread_cond_t cond;//条件变量
pthread_t *tids;//线程id
int thread_nums;//需创建的线程的数量
struct task *head;任务头结点
int cur_queue_size;//标记为控制条件变量的阻塞wait
};
2.添加任务----》初始化任务链表,添加节点
pool_add_task(void*(*pro)(void *),void *arg)
{
struct task *new = malloc(sizeof(struct task));//初始化任务结构体
new->p = pro;
new->arg = arg;
new->next = NULL;
pthread_mutex_lock(&(pool->mutex));//对公共资源操作时,记住时常上锁,解锁
struct task *lastnode = pool->head;
if(lastnode == NULL)//两种情况,判断头结点是否为空
{
pool->head = new;
}
//?????前面几句如果改成lastnode = new;出现段错误。原因:任务链表是struct pthread_pool的一个成员,而pool->head是任务链表的头。struct task *lastnode = pool->head;
else
{
while(lastnode->next!=NULL)//头结点不为空的情况
{
lastnode = lastnode->next;
}
lastnode->next = new;
}
pool->cur_queue_size++;//每添加一个结点,标记位+1
// printf("%d\n",*(int *)(new->arg));
// printf("%d\n",pool->cur_queue_size);
pthread_mutex_unlock(&(pool->mutex));
pthread_cond_signal(&pool->cond);//向处于阻塞状态的线程发送唤醒信号
}
3.线程初始化----》创建线程(功能函数)
void pool_init(int thread_num)
{
//对线程池结构体初始化
pool = malloc(sizeof(struct pthread_pool));
pthread_mutex_init(&(pool->mutex),NULL);
pthread_cond_init(&(pool->cond),NULL);
pool->thread_nums = thread_num;
pool->head = NULL;
pool->cur_queue_size = 0;
pool->tids = malloc(thread_num*sizeof(pthread_t));
int i = 0;
for(i=0;i<thread_num;i++)
{
pthread_create(&(pool->tids[i]),NULL,thread_r,NULL);
// printf("pool init\n");
}
}
4.任务函数(从任务链表的头部扣下结点,执行结构体中的函数)
void* thread_r(void*p)
{
while(1)
{
pthread_mutex_lock(&(pool->mutex));
while(pool->cur_queue_size == 0)
// printf("wait\n"); //ok
pthread_cond_wait(&(pool->cond),&(pool->mutex));
// printf("wait!\n");
struct task *q = pool->head;
// printf("q jiedian\n");
pool->head = q->next;
// printf("pool->next\n");
q->next = NULL;
// printf("put in error\n");
pool->cur_queue_size--;
pthread_mutex_unlock(&pool->mutex);
// printf("pthred_r\n");
(*(q->p))(q->arg);//执行结构体中的函数
free(q);
q = NULL;
// if(pool->cur_queue_size ==0)
// break;
}
}
5.功能函数中的函数指针。
void *f1(void *arg)
{
int a = *(int*)arg;
// sleep(1);
printf("%d\n",a);
}
main函数:(如何销毁线程池,需待解)
int main()
{
pool_init(3);
// printf("pthread pool is start\n");
// sleep(1);
int a=12;
pool_add_task(f1,(void*)&a);
// sleep(2);
// printf("pool_add_task\n");
pool_add_task(f1,(void*)&a);
pool_add_task(f1,(void*)&a);
// sleep(5);
pthread_join(pool->tids[0],NULL);
pthread_join(pool->tids[1],NULL);
pthread_join(pool->tids[2],NULL);
}
struct task{
void *(*p)(void*);//需要实现的函数;
void *arg;//函数所带的参数
struct task *next;
};
struct pthread_pool{
pthread_mutex_t mutex;//线程锁
pthread_cond_t cond;//条件变量
pthread_t *tids;//线程id
int thread_nums;//需创建的线程的数量
struct task *head;任务头结点
int cur_queue_size;//标记为控制条件变量的阻塞wait
};
2.添加任务----》初始化任务链表,添加节点
pool_add_task(void*(*pro)(void *),void *arg)
{
struct task *new = malloc(sizeof(struct task));//初始化任务结构体
new->p = pro;
new->arg = arg;
new->next = NULL;
pthread_mutex_lock(&(pool->mutex));//对公共资源操作时,记住时常上锁,解锁
struct task *lastnode = pool->head;
if(lastnode == NULL)//两种情况,判断头结点是否为空
{
pool->head = new;
}
//?????前面几句如果改成lastnode = new;出现段错误。原因:任务链表是struct pthread_pool的一个成员,而pool->head是任务链表的头。struct task *lastnode = pool->head;
else
{
while(lastnode->next!=NULL)//头结点不为空的情况
{
lastnode = lastnode->next;
}
lastnode->next = new;
}
pool->cur_queue_size++;//每添加一个结点,标记位+1
// printf("%d\n",*(int *)(new->arg));
// printf("%d\n",pool->cur_queue_size);
pthread_mutex_unlock(&(pool->mutex));
pthread_cond_signal(&pool->cond);//向处于阻塞状态的线程发送唤醒信号
}
3.线程初始化----》创建线程(功能函数)
void pool_init(int thread_num)
{
//对线程池结构体初始化
pool = malloc(sizeof(struct pthread_pool));
pthread_mutex_init(&(pool->mutex),NULL);
pthread_cond_init(&(pool->cond),NULL);
pool->thread_nums = thread_num;
pool->head = NULL;
pool->cur_queue_size = 0;
pool->tids = malloc(thread_num*sizeof(pthread_t));
int i = 0;
for(i=0;i<thread_num;i++)
{
pthread_create(&(pool->tids[i]),NULL,thread_r,NULL);
// printf("pool init\n");
}
}
4.任务函数(从任务链表的头部扣下结点,执行结构体中的函数)
void* thread_r(void*p)
{
while(1)
{
pthread_mutex_lock(&(pool->mutex));
while(pool->cur_queue_size == 0)
// printf("wait\n"); //ok
pthread_cond_wait(&(pool->cond),&(pool->mutex));
// printf("wait!\n");
struct task *q = pool->head;
// printf("q jiedian\n");
pool->head = q->next;
// printf("pool->next\n");
q->next = NULL;
// printf("put in error\n");
pool->cur_queue_size--;
pthread_mutex_unlock(&pool->mutex);
// printf("pthred_r\n");
(*(q->p))(q->arg);//执行结构体中的函数
free(q);
q = NULL;
// if(pool->cur_queue_size ==0)
// break;
}
}
5.功能函数中的函数指针。
void *f1(void *arg)
{
int a = *(int*)arg;
// sleep(1);
printf("%d\n",a);
}
main函数:(如何销毁线程池,需待解)
int main()
{
pool_init(3);
// printf("pthread pool is start\n");
// sleep(1);
int a=12;
pool_add_task(f1,(void*)&a);
// sleep(2);
// printf("pool_add_task\n");
pool_add_task(f1,(void*)&a);
pool_add_task(f1,(void*)&a);
// sleep(5);
pthread_join(pool->tids[0],NULL);
pthread_join(pool->tids[1],NULL);
pthread_join(pool->tids[2],NULL);
}
相关文章推荐
- 蓝桥杯 运动员分组
- Codeforces 533B 树上的dp(求最大偶数个节点的权重和)
- MS SQL SERVER 聚簇索引和非聚簇索引区别
- BZOJ3653: 谈笑风生
- PB中TreeView控件使用技巧
- RHCE考试经验
- 希尔排序
- C++开发人脸性别识别总结
- 1017. Queueing at Bank (25)
- 【CodeForces】A. Dragons
- 排序--面经
- android学习日记03-第一次创建项目错误解决
- C语言深度剖析-----多维数组和多维指针
- HBase 源码阅读之 读过程及scanner
- volatile关键字与线程间通信
- lucene-查询query->WildcardQuery使用通配符搜索
- Android中的单例模式
- 判断手机操作系统版本是否允许运行程序
- Can not find the tag library descriptor for "/struts-tags"`
- ORACLE11g“空表”无法导出的深入分析