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 + -
显示快捷键?