thread.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 677 行 · 第 1/2 页
CPP
677 行
while(thread_info->sleep_condition.timed_wait(lk,st)); } else { xtime const xt=get_xtime(st); for (int foo=0; foo < 5; ++foo) {# if defined(BOOST_HAS_PTHREAD_DELAY_NP) timespec ts; to_timespec_duration(xt, ts); BOOST_VERIFY(!pthread_delay_np(&ts));# elif defined(BOOST_HAS_NANOSLEEP) timespec ts; to_timespec_duration(xt, ts); // nanosleep takes a timespec that is an offset, not // an absolute time. nanosleep(&ts, 0);# else mutex mx; mutex::scoped_lock lock(mx); condition cond; cond.timed_wait(lock, xt);# endif xtime cur; xtime_get(&cur, TIME_UTC); if (xtime_cmp(xt, cur) <= 0) return; } } } void yield() {# if defined(BOOST_HAS_SCHED_YIELD) BOOST_VERIFY(!sched_yield());# elif defined(BOOST_HAS_PTHREAD_YIELD) BOOST_VERIFY(!pthread_yield());# else xtime xt; xtime_get(&xt, TIME_UTC); sleep(xt);# endif } } unsigned thread::hardware_concurrency() {#if defined(PTW32_VERSION) || defined(__hpux) return pthread_num_processors_np();#elif defined(__linux__) return get_nprocs();#elif defined(__APPLE__) || defined(__FreeBSD__) int count; size_t size=sizeof(count); return sysctlbyname("hw.ncpu",&count,&size,NULL,0)?0:count;#elif defined(BOOST_HAS_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN) int const count=sysconf(_SC_NPROCESSORS_ONLN); return (count>0)?count:0;#else return 0;#endif } thread::id thread::get_id() const { detail::thread_data_ptr const local_thread_info=get_thread_info(); if(local_thread_info) { return id(local_thread_info); } else { return id(); } } void thread::interrupt() { detail::thread_data_ptr const local_thread_info=get_thread_info(); if(local_thread_info) { lock_guard<mutex> lk(local_thread_info->data_mutex); local_thread_info->interrupt_requested=true; if(local_thread_info->current_cond) { BOOST_VERIFY(!pthread_cond_broadcast(local_thread_info->current_cond)); } } } bool thread::interruption_requested() const { detail::thread_data_ptr const local_thread_info=get_thread_info(); if(local_thread_info) { lock_guard<mutex> lk(local_thread_info->data_mutex); return local_thread_info->interrupt_requested; } else { return false; } } thread::native_handle_type thread::native_handle() { detail::thread_data_ptr const local_thread_info=get_thread_info(); if(local_thread_info) { lock_guard<mutex> lk(local_thread_info->data_mutex); return local_thread_info->thread_handle; } else { return pthread_t(); } } namespace this_thread { thread::id get_id() { boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data(); return thread::id(thread_info?thread_info->shared_from_this():detail::thread_data_ptr()); } void interruption_point() { boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data(); if(thread_info && thread_info->interrupt_enabled) { lock_guard<mutex> lg(thread_info->data_mutex); if(thread_info->interrupt_requested) { thread_info->interrupt_requested=false; throw thread_interrupted(); } } } bool interruption_enabled() { boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data(); return thread_info && thread_info->interrupt_enabled; } bool interruption_requested() { boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data(); if(!thread_info) { return false; } else { lock_guard<mutex> lg(thread_info->data_mutex); return thread_info->interrupt_requested; } } disable_interruption::disable_interruption(): interruption_was_enabled(interruption_enabled()) { if(interruption_was_enabled) { detail::get_current_thread_data()->interrupt_enabled=false; } } disable_interruption::~disable_interruption() { if(detail::get_current_thread_data()) { detail::get_current_thread_data()->interrupt_enabled=interruption_was_enabled; } } restore_interruption::restore_interruption(disable_interruption& d) { if(d.interruption_was_enabled) { detail::get_current_thread_data()->interrupt_enabled=true; } } restore_interruption::~restore_interruption() { if(detail::get_current_thread_data()) { detail::get_current_thread_data()->interrupt_enabled=false; } } } namespace detail { void add_thread_exit_function(thread_exit_function_base* func) { detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); thread_exit_callback_node* const new_node= new thread_exit_callback_node(func,current_thread_data->thread_exit_callbacks); current_thread_data->thread_exit_callbacks=new_node; } tss_data_node* find_tss_data(void const* key) { detail::thread_data_base* const current_thread_data(get_current_thread_data()); if(current_thread_data) { detail::tss_data_node* current_node=current_thread_data->tss_data; while(current_node) { if(current_node->key==key) { return current_node; } current_node=current_node->next; } } return NULL; } void* get_tss_data(void const* key) { if(tss_data_node* const current_node=find_tss_data(key)) { return current_node->value; } return NULL; } void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing) { if(tss_data_node* const current_node=find_tss_data(key)) { if(cleanup_existing && current_node->func) { (*current_node->func)(current_node->value); } current_node->func=func; current_node->value=tss_data; } else { detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); tss_data_node* const new_node=new tss_data_node(key,func,tss_data,current_thread_data->tss_data); current_thread_data->tss_data=new_node; } } }// thread_group::thread_group()// {// }// thread_group::~thread_group()// {// // We shouldn't have to scoped_lock here, since referencing this object// // from another thread while we're deleting it in the current thread is// // going to lead to undefined behavior any way.// for (std::list<thread*>::iterator it = m_threads.begin();// it != m_threads.end(); ++it)// {// delete (*it);// }// }// thread* thread_group::create_thread(const function0<void>& threadfunc)// {// // No scoped_lock required here since the only "shared data" that's// // modified here occurs inside add_thread which does scoped_lock.// std::auto_ptr<thread> thrd(new thread(threadfunc));// add_thread(thrd.get());// return thrd.release();// }// void thread_group::add_thread(thread* thrd)// {// mutex::scoped_lock scoped_lock(m_mutex);// // For now we'll simply ignore requests to add a thread object multiple// // times. Should we consider this an error and either throw or return an// // error value?// std::list<thread*>::iterator it = std::find(m_threads.begin(),// m_threads.end(), thrd);// BOOST_ASSERT(it == m_threads.end());// if (it == m_threads.end())// m_threads.push_back(thrd);// }// void thread_group::remove_thread(thread* thrd)// {// mutex::scoped_lock scoped_lock(m_mutex);// // For now we'll simply ignore requests to remove a thread object that's// // not in the group. Should we consider this an error and either throw or// // return an error value?// std::list<thread*>::iterator it = std::find(m_threads.begin(),// m_threads.end(), thrd);// BOOST_ASSERT(it != m_threads.end());// if (it != m_threads.end())// m_threads.erase(it);// }// void thread_group::join_all()// {// mutex::scoped_lock scoped_lock(m_mutex);// for (std::list<thread*>::iterator it = m_threads.begin();// it != m_threads.end(); ++it)// {// (*it)->join();// }// }// void thread_group::interrupt_all()// {// boost::lock_guard<mutex> guard(m_mutex); // for(std::list<thread*>::iterator it=m_threads.begin(),end=m_threads.end();// it!=end;// ++it)// {// (*it)->interrupt();// }// } // size_t thread_group::size() const// {// return m_threads.size();// }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?