一个简单线程池的实现---需进一步完善

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个简单线程池的实现---需进一步完善相关的知识,希望对你有一定的参考价值。

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;出现段错误。无解
 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);

}

以上是关于一个简单线程池的实现---需进一步完善的主要内容,如果未能解决你的问题,请参考以下文章

线程池的简单使用

线程池的简单使用

一个简单线程池的实现

自己实现一个简单的线程池

线程池的简单实现

Linux下简单线程池的实现