惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
罗磊的独立博客
雷峰网
雷峰网
量子位
V
Visual Studio Blog
Vercel News
Vercel News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The Cloudflare Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
宝玉的分享
宝玉的分享
月光博客
月光博客
Martin Fowler
Martin Fowler
aimingoo的专栏
aimingoo的专栏
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Microsoft Security Blog
Microsoft Security Blog
博客园 - 叶小钗
腾讯CDC
Engineering at Meta
Engineering at Meta
博客园 - Franky
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
Jina AI
Jina AI
A
About on SuperTechFans

博客园 - 小水坝

使用双分派解决领域实体和外部机制通信问题 搞定thrift双向消息 读《软件需求最佳实践》有感 【thrift】vc中使用thrift中文字符串乱码问题解决 __declspec(dllimport)的小秘密(转) 跨线程send message 【boost】使用serialization库序列化子类 【boost】ptree 读写中文的问题 动态创建TeeChart的简便方法 【MFC】动态创建CMFCToolbar图标不显示问题 【VC】VC工具栏图标合并工具(非tbcreator和visual toolbar) 【boost】使用lambda表达式和generate_n生成顺序序列 【boost】BOOST_LOCAL_FUNCTION体验 【boost】MFC dll中使用boost thread的问题 【转帖】C++编译原理 资料 IE6,7下password框长度变短问题 dwz局部表格分页 dwz中combox的value问题 dwz中使用flot,js报表等js插件
【boost】使用装饰者模式改造boost::thread_group
小水坝 · 2013-09-10 · via 博客园 - 小水坝

在项目中使用boost::thread_group的时候遇到几个问题:

1、thread_group不提供删除全部thread列表的方法,一直使用create会是其内部列表不断增加。

2、thread_group不提供try_join_for等方法,在线程中等待时,无法调用peekmessage函数来重新激活消息队列。

由于thread_group的接口本来就比较小,因此可以直接重写,但是这个时候使用装饰者模式无疑更加方便。

namespace boost
{
    class thread_group_ex
    {
    private:
        thread_group_ex(thread_group_ex const&);
        thread_group_ex& operator=(thread_group_ex const&);
    public:
        thread_group_ex(){}
        ~thread_group_ex(){}

        bool is_this_thread_in()
        {
            return m_thread_group.is_this_thread_in();
        }

        bool is_thread_in(thread* thrd)
        {
            return m_thread_group.is_thread_in(thrd);
        }

        template<typename F>
        thread* create_thread(F threadfunc)
        {
            thread* pthread = m_thread_group.create_thread(threadfunc);
            m_list_ex.push_back(pthread);
            return pthread;
        }

        void add_thread(thread* thrd)
        {
            m_thread_group.add_thread(thrd);
            if (thrd)
            {
                m_list_ex.push_back(thrd);
            }
        }

        void remove_thread(thread* thrd)
        {
            m_thread_group.remove_thread(thrd);
            m_list_ex.remove(thrd);
        }

        void join_all()
        {
            m_thread_group.join_all();
        }
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
        void interrupt_all()
        {
            m_thread_group.interrupt_all();
        }
#endif
        size_t size() const
        {
            return m_thread_group.size();
        }
        //try join all方法
        //非阻塞等待所有线程返回
        void try_join_all()
        {
            boost::shared_lock<shared_mutex> guard(m_ex);

            MSG msg;

            for (list<thread *>::iterator it=m_list_ex.begin(); it!=m_list_ex.end(); ++it)
            {
                if ((*it)->joinable())
                {
                    while (!(*it)->try_join_for(chrono::milliseconds(wait_milliseconds)))
                    {
                        PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
                    }
                }
            }
        }
        //清空列表方法
        void remove_all_thread()
        {
            boost::shared_lock<shared_mutex> guard(m_ex);
            for (list<thread *>::iterator it=m_list_ex.begin(); it!=m_list_ex.end(); ++it)
            {
                m_thread_group.remove_thread(*it);
                delete (*it);
            }    
            m_list_ex.clear();
        }

    private:
        const static UINT wait_milliseconds = 50;
        thread_group m_thread_group;
        list<thread *> m_list_ex;
        mutable shared_mutex m_ex;
    };
}