Example #1
0
//加任务
void threadpool_add_task(threadpool_t *pool, void *(*run)(void *arg),void *arg)
{
	task_t *newstask = (task_t *)malloc(sizeof(task_t));
	newstask->run = run;
	newstask->arg = arg;
	newstask -> next = NULL;
	
	condition_lock(&pool -> ready);
	//将任务添加到对列中
	if(pool -> first ==NULL)
	{
		pool -> first = newstask;
	}
	else
		pool -> last -> next = newstask;
	pool -> last = newstask;
	//如果有等待线程,则唤醒其中一个
	if(pool -> idle > 0)
	{
		condition_signal(&pool -> ready);
	}
	else if(pool -> counter < pool -> max_threads)
	{
		pthread_t tid;
		pthread_create(&tid,NULL,thread_routine,pool);
		pool -> counter++;
	}
	condition_unlock(&pool -> ready);
}
Example #2
0
/* 销毁线程池 */
void threadpool_destroy( threadpool_t* pool ) 
{
   if ( pool->quit ) 
   {
      return ;
   } 

   /************************** 进入临界区 ***********************/

   condition_lock( &pool->ready ) ;

   // 设置退出标志为真
   pool->quit = 1 ;

   // 如果线程池中正在运行着线程,那么我们需要等待线程执行完毕再销毁
   if ( pool->counter > 0 ) 
   {
      if ( pool->idle > 0 )
      {
         condition_broadcast( &pool->ready ) ;
      }
      while ( pool->counter > 0 ) 
      {
         condition_wait( &pool->ready ) ; // 主线程(main 函数所在线程)将等待在条件变量上
      }
   }

   condition_unlock( &pool->ready ) ;

   /************************** 退出临界区 ***********************/
   
   // 销毁条件变量
   condition_destroy( &pool->ready ) ;
}
Example #3
0
/* 向线程池中添加线程 */
void threadpool_add_task( threadpool_t* pool, void* (*run)( void* arg ), void* arg ) 
{
   task_t* newtask = ( task_t* ) malloc ( sizeof( task_t ) ) ; // 创建线程控制块
   newtask->run = run ; // 设置线程的回调函数
   newtask->arg = arg ; // 设置回调函数的参数
   newtask->next = NULL ; // 新加入的线程会被添加到链表尾部

   /************************** 进入临界区 ***********************/

   condition_lock( &pool->ready ) ; // 拿到互斥锁

   // 把新创建的 TCB 添加到线程链表中
   if ( pool->first == NULL ) 
   {
   	  // 如果线程链表为空,则 TCB 作为链表头部
      pool->first = newtask ;
   }
   else
   {
   	  // 如果线程链表不为空,加入到链表尾部
      pool->last->next = newtask ;
   }
   pool->last = newtask ; // 修改链表尾指针
   
   // 如果有空闲线程,那么就唤醒空闲线程
   if ( pool->idle > 0 ) 
   {
      condition_signal( &pool->ready ) ; // 通知等待在条件变量上的空闲线程
   }
   else if ( pool->counter < pool->max_threads ) 
   {
   	  // 如果没有空闲线程可用,而且当前线程数量小于线程池的容量,我们就创建一个线程
      pthread_t tid ;
      pthread_create( &tid, NULL, thread_runtime, pool ) ; // 指定新线程的起始函数为 thread_runtime,把线程池传递给 thread_runtime
      ++ pool->counter ;
   }

   condition_unlock( &pool->ready ) ; // 释放互斥锁

   /************************** 退出临界区 ***********************/
}
Example #4
0
void threadpool_destroy(threadpool_t* pool)
{
	if(pool->quit)
		return;

	condition_lock(&pool->ready);
	pool->quit = 1;

	if(pool->counter > 0)	
	{
		if(pool->idle > 0)
			condition_broadcast(&pool->ready);
		
		//waiting working thread exit
		while(pool->counter > 0)
			condition_wait(&pool->ready);
	}

	condition_unlock(&pool->ready);
	condition_destroy(&pool->ready);
}
Example #5
0
//销毁线程池
void  threadpool_destory(threadpool_t *pool)
{

	if(pool -> quit)
	{
		return;
	}
	condition_lock(&pool -> ready);
	pool->quit = 1;
	if(pool -> counter > 0)
	{
		if(pool -> idle > 0)
			condition_broadcast(&pool->ready);

		while(pool -> counter > 0)
		{
			condition_wait(&pool->ready);
		}
	}
	condition_unlock(&pool->ready);
	condition_destory(&pool -> ready);
}
Example #6
0
void *thread_routine(void *arg)
{
	struct timespec abstime;
	int timeout;
	printf("thread 0x%0x is starting\n",(int)pthread_self());
	threadpool_t *pool = (threadpool_t *)arg;
	while(1)
	{
		timeout = 0;
		condition_lock(&pool -> ready);
		pool -> idle++;
		//等待队列有任务到来或者线程池销毁的通知
		while(pool -> first == NULL && !pool -> quit)
		{
			printf("thread 0x%0x is waiting\n",(int)pthread_self());
			clock_gettime(CLOCK_REALTIME,&abstime);
			abstime.tv_sec += 2;
			int status=condition_timewait(&pool -> ready,&abstime);
			if(status == ETIMEDOUT)
			{
				printf("thread 0x%0x is wait timed out\n",(int)pthread_self());
				timeout = 1;
				break;
			}

		}
		//等到到条件,处于工作状态
		pool -> idle--;

	    if(pool -> first != NULL)
		{
			task_t *t = pool -> first;
			pool -> first = t -> next;
			//需要先解锁,以便添加新任务。其他消费者线程能够进入等待任务。
			condition_unlock(&pool -> ready);
			t -> run(t->arg);
			free(t);
			condition_lock(&pool -> ready);
		}
		//等待线程池销毁的通知
		if(pool -> quit && pool ->first == NULL)
		{
			pool -> counter--;
			if(pool->counter == 0)
			{
				condition_signal(&pool -> ready);
			}
			condition_unlock(&pool->ready);
			//跳出循环之前要记得解锁
			break;
		}

		if(timeout &&pool -> first ==NULL)
		{
			pool -> counter--;
			condition_unlock(&pool->ready);
			//跳出循环之前要记得解锁
			break;
		}
		condition_unlock(&pool -> ready);
	}

	printf("thread 0x%0x is exiting\n",(int)pthread_self());
	return NULL;
}
Example #7
0
void* thread_routine(void* arg)
{
	struct timespec abstime;
	int timeout;	

	printf("thread 0x%x is starting ...\n", (int)pthread_self());
	threadpool_t* pool = (threadpool_t*)arg;

	while(1)
	{
  		timeout = 0;
		condition_lock(&pool->ready);
		pool->idle++;		

		while(pool->first == NULL && !pool->quit)
		{
			printf("thread 0x%x is waiting ...\n", (int)pthread_self());
	
			clock_gettime(CLOCK_REALTIME, &abstime);
			abstime.tv_sec += 2;
		
			int status = condition_timewait(&pool->ready, &abstime);	
			if(status == ETIMEDOUT)	
			{
				printf("thread 0x%x is wait timed out ...\n", (int)pthread_self());
				timeout = 1;
				break;
			}	
		}

		pool->idle--;

		if(pool->first != NULL)
		{
			task_t* t = pool->first;
			pool->first = t->next;
			
			condition_unlock(&pool->ready);
			t->run(t->arg);
			free(t);
			condition_lock(&pool->ready);			
		}	

		if(pool->quit && pool->first == NULL)
		{
			if(--pool->counter == 0)
				condition_signal(&pool->ready);

			condition_unlock(&pool->ready);
			break;
		}

		if(timeout && pool->first == NULL)
		{
			pool->counter--;
                        condition_unlock(&pool->ready);
                        break;
		}
		condition_unlock(&pool->ready);
	}

	printf("thread 0x%x is exiting ...\n", (int)pthread_self());
	return NULL;
}
Example #8
0
/* 线程入口函数 */
void* thread_runtime( void* arg ) 
{
   struct timespec abstime ;
   int timeout ;
   
   // 拿到线程池对象
   threadpool_t* pool = ( threadpool_t* ) arg ;

   while ( 1 ) 
   {
      timeout = 0 ;

      /************************** 进入临界区 ***********************/

      condition_lock( &pool->ready ) ;
      
      // 空闲线程数加 1
      ++ pool->idle ;

      // 如果线程链表为空,而且线程池处于运行状态,那么线程就该等待任务的到来
      while ( pool->first == NULL && pool->quit == 0 )
      {
         printf( "thread 0x%x is waiting\n", (int)pthread_self() ) ;
         clock_gettime( CLOCK_REALTIME, &abstime ) ;
         abstime.tv_sec += 2 ;
         int status = condition_timedwait( &pool->ready, &abstime ) ;
         if ( status == ETIMEDOUT )
         {
            printf( "thread 0x%x is wait timed out\n", (int)pthread_self() ) ;
            timeout = 1 ;
            break ;
         }
      }

      // 如果线程等待超时
      if ( timeout && pool->first == NULL )
      {
         -- pool->counter ; // 那么线程数量减 1
         condition_unlock( &pool->ready ) ; // 释放互斥锁
         break ; // 跳出 while,注意,break 之后,线程入口函数执行完毕,线程将不复存在
      }

      // 线程获得任务
      -- pool->idle ; // 线程池空闲数减 1
      if ( pool->first != NULL )
      {
         task_t* t = pool->first ; // 从链表头部取出 TCB
         pool->first = t->next ; // 指向下一个 TCB

         // 执行任务需要一定时间,所以要先解锁
         // 以便生产者可以往链表中加入任务
         // 以及其他消费者可以等待任务
         condition_unlock( &pool->ready ) ;

         t->run( t->arg ) ; // 执行任务的回调函数

         free( t ) ; // 任务执行完毕,销毁 TCB

         condition_lock( &pool->ready ) ;
      } 

      // quit == 1 说明要销毁线程池
      if ( pool->quit && pool->first == NULL )
      {
         -- pool->counter ;
         if ( pool->counter == 0 ) 
         {
            condition_signal( &pool->ready ) ; // 唤醒等待在条件变量上的主线程
         }
         condition_unlock( &pool->ready ) ;
         break ;
      }

      condition_unlock( &pool->ready ) ;

      /************************** 退出临界区 ***********************/
   }

   return NULL ;
}