代码之家  ›  专栏  ›  技术社区  ›  t.g.

boost.thread死锁和自删除

  •  3
  • t.g.  · 技术社区  · 15 年前

    boost::thread_group 创建(使用) thread_group::create_thread() )并分派线程。为了限制 最大线程数,在每个线程结束时,我移除线程 从 thread_group 然后删除线程本身(这样我就可以 决定是否需要创建新线程)。不管它挂在哪里 在创建和删除最后一个线程之间(比如

    我的问题是:

    • 为什么我的代码挂起?

    以下是相关代码:

    //1-创建和分派线程的代码

     { 
            //mutex for map<thread_id, thread*> operations 
            boost::mutex::scoped_lock lk(m_mutex_for_ptr); 
    
            // create a thread for this->f(duplicate_hashes) 
            boost::thread* p = m_thread_group.create_thread(boost::bind( 
                &detectiveT<equal_predicate>::f, 
                this, 
                duplicate_hashes 
                )); 
    
            // save the <thread_id,thread pointer> map for later lookup & deletion 
            m_thread_ptrs.insert(make_pair(p->get_id(), p)); 
    
            // log to console for debug 
            cout << "thread created: " 
                << p->get_id() << ", " 
                << m_thread_group.size() << ", " m_thread_ptrs.size() << 
    "\n";     
        }   
    

    //2-线程执行的代码

    void f(list<map_iterator_type>& l) 
    { 
        Do_something(l);    
        boost::this_thread::at_thread_exit(boost::bind( 
            &detectiveT<equal_predicate>::remove_this_thread, 
            this 
            ));                     
    } 
    

    //3-删除线程本身的代码

    void remove_this_thread() 
    { 
    
        { 
            //mutex for map<thread_id, thread*> operations 
            boost::mutex::scoped_lock lk(m_mutex_for_ptr);                   
            boost::thread::id this_id(boost::this_thread::get_id()); 
    
            map<boost::thread::id, boost::thread*>::iterator itr; 
    
            itr = (m_thread_ptrs.find(this_id)); 
    
            if(m_thread_ptrs.end() != itr) 
            { 
                // remove it from the control of thread_group 
                m_thread_group.remove_thread(itr->second); 
                // delete it 
                delete itr->second; 
    
                // remove from the map 
                m_thread_ptrs.erase(this_id); 
    
                // log to console for debug 
                cout << "thread erased: " 
                    << this_id << ", " 
                    << m_thread_group.size() << ", " 
                    << m_thread_ptrs.size() << "\n";             
            } 
        }               
    }
    
    1 回复  |  直到 12 年前
        1
  •  4
  •   rpg    15 年前

    既然创建/销毁是昂贵的,为什么不尝试回收线程呢?

    编写线程池类的代码并向其发送任务。如果池中没有更多可用线程,则池将对任务进行排队;如果池中有当前线程,则池将创建线程<最大线程数或仅使用可用线程数。

    建议的实施:

    根据您希望的复杂程度,您可以一次在池中创建所有线程,或者在当前线程计数时添加线程<理想的线程数,所有现有线程都忙于执行任务。

    线程不会被破坏 .

    你必须做一些同步;最简单的方法是尝试并找到一个可用的线程池实现,比如Windows中的线程池(我认为是Vista+或QtConcurrent),它允许您传递任务、调用run并让OS/库担心一切。

    稍后编辑:

    http://threadpool.sourceforge.net/