static inline void msgque_sync_pop(ptq_t ptq,int32_t timeout) { msgque_t que = ptq->que; mutex_lock(que->mtx); if(timeout > 0){ if(llist_is_empty(&que->share_que) && timeout){ uint64_t end = GetSystemMs64() + (uint64_t)timeout; dlist_push(&que->blocks,&ptq->read_que.bnode); do{ if(0 != condition_timedwait(ptq->cond,que->mtx,timeout)){ //timeout dlist_remove(&ptq->read_que.bnode); break; } uint64_t l_now = GetSystemMs64(); if(l_now < end) timeout = end - l_now; else break;//timeout }while(llist_is_empty(&que->share_que)); } } /*else if(llist_is_empty(&que->share_que)) { dlist_push(&que->blocks,&ptq->read_que.bnode); do{ condition_wait(ptq->cond,que->mtx); }while(llist_is_empty(&que->share_que)); }*/ if(!llist_is_empty(&que->share_que)) llist_swap(&ptq->local_que,&que->share_que); mutex_unlock(que->mtx); }
void thread_suspend(thread_t t,int32_t ms) { pthread_t self = pthread_self(); #ifdef _MINGW_ if(self.p != t->threadid.p || self.x != t->threadid.x) return; #else if(self != t->threadid) return;//只能挂起自己 #endif mutex_lock(t->mtx); if(0 >= ms) { t->is_suspend = 1; while(t->is_suspend) { condition_wait(t->cond,t->mtx); } } else { t->is_suspend = 1; condition_timedwait(t->cond,t->mtx,ms); t->is_suspend = 0; } mutex_unlock(t->mtx); }
void thread_suspend(thread_t t,int ms) { pthread_t self = pthread_self(); if(self != t->threadid) return;//只能挂起自己 mutex_lock(t->mtx); if(0 >= ms) { t->is_suspend = 1; while(t->is_suspend) { condition_wait(t->cond,t->mtx); } } else { t->is_suspend = 1; condition_timedwait(t->cond,t->mtx,ms); t->is_suspend = 0; } mutex_unlock(t->mtx); }
static inline mq_sync_pop(mq_t m,struct per_thread_struct *pts,uint32_t timeout) { mutex_lock(m->mtx); if(link_list_is_empty(m->share_list)) { if(timeout) { while(link_list_is_empty(m->share_list)) { double_link_push(&m->blocks,&pts->block); if(0 != condition_timedwait(pts->cond,m->mtx,timeout)) { double_link_remove(&pts->block); break; } } } } link_list_swap(pts->local_pop_q,m->share_list); mutex_unlock(m->mtx); }
/* 线程入口函数 */ 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 ; }