nginx线程池源码分析

2019-10-17 20:02:28丽君

 6.添加任务

  首先申请一个任务节点,实例化后将节点加入任务队列,并将当前任务队列数++并通知其他进程有新任务。整个过程加锁。

int zoey_threadpool_add_task(zoey_threadpool_t *pool, CB_FUN handler, void* argv)
{
  zoey_task_t *task = NULL;
  //申请一个任务节点并赋值
  task = (zoey_task_t *)malloc(sizeof(zoey_task_t));
  if (task == NULL){
    return -1;
  }
  task->handler = handler;
  task->argv = argv;
  task->next = NULL;
  if (pthread_mutex_lock(&pool->mutex) != 0){ //加锁
    free(task);
    return -1;
  }
  do{

    if (pool->tasks.curtasknum >= pool->tasks.maxtasknum){//判断工作队列中的任务数是否达到限制
      break;
    }

    //将任务节点尾插到任务队列
    *(pool->tasks.tail) = task;
    pool->tasks.tail = &task->next;
    pool->tasks.curtasknum++;

    //通知阻塞的线程
    if (pthread_cond_signal(&pool->cond) != 0){
      break;
    }
    //解锁
    pthread_mutex_unlock(&pool->mutex);
    return 0;

  }while(0);
  pthread_mutex_unlock(&pool->mutex);
  free(task);
  return -1;

}

 7.销毁线程池

  销毁线程池其实也是向任务队列添加任务,只不过添加的任务是让线程退出。z_threadpool_exit_cb函数会将lock置0后退出线程,lock为0表示此线程

  已经退出,接着退出下一个线程。退出完线程释放所有资源。

void zoey_threadpool_destroy(zoey_threadpool_t *pool)
{
  unsigned int n = 0;
  volatile unsigned int lock;

  //z_threadpool_exit_cb函数会使对应线程退出
  for (; n < pool->threadnum; n++){
    lock = 1;
    if (zoey_threadpool_add_task(pool, z_threadpool_exit_cb, &lock) != 0){
      return;
    }
    while (lock){
      usleep(1);
    }
  }
  z_thread_mutex_destroy(&pool->mutex);
  z_thread_cond_destroy(&pool->cond);
  z_thread_key_destroy();
  free(pool);
}

 8.增加一个线程

  很简单,再生成一个线程以及线程数++即可。加锁。

int zoey_thread_add(zoey_threadpool_t *pool)
{
  int ret = 0;
  if (pthread_mutex_lock(&pool->mutex) != 0){
    return -1;
  }
  ret = z_thread_add(pool);
  pthread_mutex_unlock(&pool->mutex);
  return ret;
}

 9.改变任务队列最大任务限制

  当num=0时设置线程数为无限大。

void zoey_set_max_tasknum(zoey_threadpool_t *pool,unsigned int num)
{
  if (pthread_mutex_lock(&pool->mutex) != 0){
    return -1;
  }
  z_change_maxtask_num(pool, num); //改变最大任务限制
  pthread_mutex_unlock(&pool->mutex);
}

  10.使用示例

int main()
{
  int array[10000] = {0};
  int i = 0;
  zoey_threadpool_conf_t conf = {5,0,5}; //实例化启动参数
  zoey_threadpool_t *pool = zoey_threadpool_init(&conf);//初始化线程池
  if (pool == NULL){
    return 0;
  }
  for (; i < 10000; i++){
    array[i] = i;
    if (i == 80){
      zoey_thread_add(pool); //增加线程
      zoey_thread_add(pool);
    }
    
    if (i == 100){
      zoey_set_max_tasknum(pool, 0); //改变最大任务数  0为不做上限
    }
    while(1){
      if (zoey_threadpool_add_task(pool, testfun, &array[i]) == 0){
        break;
      }
      printf("error in i = %dn",i);
    
    }
  }
  zoey_threadpool_destroy(pool);

  while(1){
    sleep(5);
  }
  return 0;
}