static void *do_work(void *owning_pool) { thread_pool_t *pool =(thread_pool_t *)owning_pool; state_t mystate = PRUN; task_fun mytask = NULL; void *myarg = NULL; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_cleanup_push((task_fun)pthread_mutex_unlock, (void *)&pool->mutex); for( ; ; ) { pthread_mutex_lock(&pool->mutex); while((pool->task.head == NULL) && (pool->emg_task.head == NULL)) { if(pool->worker.cur > pool->worker.min || pool->state == PEXIT) { mystate = PEXIT; break; } pthread_cond_wait(&pool->job_posted, &pool->mutex); } if(mystate == PEXIT) { del_worker(&pool->worker, pthread_self()); break; } //printf("start get task queue\n"); if(get_task(&pool->emg_task, &mytask, &myarg) == -1) { //if emergency queue is null, get normal task get_task(&pool->task, &mytask, &myarg); } pthread_cond_signal(&pool->job_taken); pthread_mutex_unlock(&pool->mutex); if(mytask) { mytask(myarg); mytask = myarg = NULL; } } pthread_cleanup_pop(1); return NULL; }
int main(int,char**) { tbb::task_scheduler_init init; // Automatic number of threads // tbb::task_scheduler_init init(2); // Explicit number of threads std::vector<mytask> tasks; for (int i=0;i<1000;++i) tasks.push_back(mytask(i)); executor exec(tasks); tbb::parallel_for(tbb::blocked_range<size_t>(0,tasks.size()),exec); std::cerr << std::endl; return 0; }
void ThreadPool::add_task(Runnable* task,THREAD_PRIORITY pri){ task_lock.lock(); task_s mytask(task,pri); tasks.push(mytask); task_lock.lock(); }
bool CMultiTaskHandler::WorkerThread( thRunParam & taskSlot ) { while( !( m_stopWorkers.load() ) ) { packaged_task<pktaskret_t()> mytask; bool shouldwaitfornewtask = false; //Grab a task if possible try { lock_guard<mutex> mylg( m_mutextasks ); if( !m_tasks.empty() ) { taskSlot.runningTask = true; mytask = std::move(m_tasks.front()); m_tasks.pop_front(); } else shouldwaitfornewtask = true; } catch( exception e ){SimpleHandleException(e);} //Run the task if( mytask.valid() ) { try { future<pktaskret_t> myfuture = mytask.get_future(); mytask(); myfuture.get(); ++m_taskcompleted; } catch( exception ) { PushException( std::current_exception() ); } //cout << "\nTask " <<m_taskcompleted <<" Complete.\n"; } taskSlot.runningTask = false; //Wait a few more microsec if the queue is empty, while hoping for a trigger of the cond var if( shouldwaitfornewtask ) { try { unique_lock<mutex> ulock( m_mutexNewTask ); m_newTask.wait_for( ulock, DUR_WORKER_THREAD_WAIT_TASK ); //unique_lock<mutex> ulock( taskSlot.newTaskmutex ); //taskSlot.newTask.wait_for( ulock, DUR_WORKER_THREAD_WAIT_TASK ); } catch( exception e ){SimpleHandleException(e);} } else { try { this_thread::sleep_for(taskSlot.waitTime); } catch( exception e ){SimpleHandleException(e);} } } return true; }