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


    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 ",*(int *)(new->arg));
    // printf("%d ",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 ");
     }
    }

    4.任务函数(从任务链表的头部扣下结点,执行结构体中的函数)

    void* thread_r(void*p)
    {
     while(1)
     { 
     
      pthread_mutex_lock(&(pool->mutex));
      while(pool->cur_queue_size == 0)
     // printf("wait "); //ok
      pthread_cond_wait(&(pool->cond),&(pool->mutex));
     
     // printf("wait! ");
      struct task *q = pool->head;
    //   printf("q jiedian ");
       pool->head = q->next;
      // printf("pool->next ");
       q->next = NULL;
      // printf("put in error ");
       pool->cur_queue_size--;
      pthread_mutex_unlock(&pool->mutex);
     // printf("pthred_r ");
      (*(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 ",a);

    }

    main函数:(如何销毁线程池,需待解)

    int main()
    {
     pool_init(3);
    // printf("pthread pool is start ");
    // sleep(1);
     int a=12;
     pool_add_task(f1,(void*)&a);
    // sleep(2);
    // printf("pool_add_task ");
     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);

    }

  • 相关阅读:
    vim删除以#,空格开头的行
    Element-ui 中对表单进行验证
    VUE页面实现加载外部HTML方法
    vue-cli2嵌入html
    文字环绕图片
    LocalDate计算两个日期相差天数
    springboot+vue脚手架使用nginx前后端分离
    通过 Netty、ZooKeeper 手撸一个 RPC 服务
    Spring Native 项目,把 Spring 项目编译成原生程序!
    印象笔记吐槽
  • 原文地址:https://www.cnblogs.com/defen/p/5232457.html
Copyright © 2020-2023  润新知