指向 boost::thread 的指针

Posted

技术标签:

【中文标题】指向 boost::thread 的指针【英文标题】:Pointer to boost::thread 【发布时间】:2012-11-29 04:27:18 【问题描述】:

我对线程的托管有疑问。

我的问题是我想创建一个 ThreadManager 类,它必须管理所有创建的线程,当然还要销毁这个线程。

class DerivedInterface

public:
    DerivedInterface():id("Test");
    virtual ~DerivedInterface();
    virtual void run() = 0;
    virtual std::string getId() = 0;
    const std::string  id ;
;

class Object : public DerivedInterface

public:
    Object():id("VirtualDae");
    ~Object()

    void run()
    

        std::cout<<"i'M IN RUN"<<std::endl;

        bool flag = true;

        while(flag)
            //allocate x resources

            try
                //do some process on resources
                boost::this_thread::sleep(boost::posix_time::milliseconds(100));
                //clean resources
            
            catch(boost::thread_interrupted const& )
            
                //clean resources
                std::cout << "Worker thread interrupted" << std::endl;
                flag = false;
            
            catch(std::exception x)
                std::cout<<"exx"<<x.what()<<std::endl;
            
        
    
    std::string getId()
        return id;
    

    const std::string  id ;
;
class ThreadManager

public:

void createThread(DerivedInterface& t)

    boost::thread t1(&DerivedInterface::run, &t); 
    insert(&t1);



     
/*
 * This method insert the pointer of the thread in a
 * map
 */

void insert(boost::thread* t1)


    boost::mutex::scoped_lock lock(m_mutex);

    int size = threadsMap.size()+1;

    std::cout<<"Size :"<<size<<std::endl;

    threadsMap.insert(std::make_pair(size, t1));


/*
 * This method return the pointer of the thread
 * inserted in a map
 */

boost::thread*  get(int key)

    boost::mutex::scoped_lock lock(m_mutex);

    if(threadsMap.find(key)!=threadsMap.end())
        std::cout<<"non null get"<<std::endl;

        return threadsMap[key];
    else
        std::cout<<" null get"<<std::endl;
        return NULL;
    



/*
 * This method stop the thread corrisponding
 * to the position pos as parameter in the map
 */
void stop(int pos)
    std::cout<<"Stop"<<std::endl;

    boost::thread* thread = get(pos);

    std::cout<<"thread  null"<<std::endl;

    if(thread != NULL)
    
        std::cout<<"thread not null"<<std::endl;
        thread->interrupt();

        std::cout << "Worker thread finished" << std::endl;
    


     private:

boost::shared_ptr<boost::thread> _mThread;

typedef std::map<int, boost::thread*> ThreadMapT;

ThreadMapT threadsMap;

std::map<int,boost::thread*>::iterator it;

boost::mutex m_mutex;

boost::thread_group g;

     ;


   int main()

    ThreadManager manager;
Object v;
//
manager.createThread(v);

std::cout<<"Interrupt"<<std::endl;

boost::thread *t1= manager.get(1);

t1->interrupt();
//
boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(10000);
if (manager.get(1)->timed_join(timeout))

    //finished
    std::cout << "Worker thread finished" << std::endl;

else

    //Not finished;
    std::cout << "Worker thread not finished" << std::endl;


       

函数 t1.interrupt 或 manager.stop 返回分段错误..

Program terminated with signal 11, Segmentation fault.
#0  0x00007f3e1d095993 in boost::thread::get_thread_info() const () from libboost_thread.so.1.51.0
(gdb) where
#0  0x00007f3e1d095993 in boost::thread::get_thread_info() const () from libboost_thread.so.1.51.0
#1  0x00007f3e1d0965c6 in boost::thread::interrupt() () from libboost_thread.so.1.51.0
#2  0x00000000004088a9 in main ()

boost::thread 的指针不为空,那会发生什么?提前谢谢你。

为什么我不能做这样的事情?

boost::thread *t1 = new boost::thread(&DerivedInterface::run, &t);

【问题讨论】:

我试过一次,found it very difficult. 顺便说一句,你的缩进都搞砸了。 【参考方案1】:
void createThread(DerivedInterface& t)

    boost::thread t1(&DerivedInterface::run, &t); 
    insert(&t1);

在上面的t1对象被创建在堆栈上,然后一个指向t1的指针被插入到映射中,然后t1超出范围并被销毁,所以所有现有的指向它的指针都变得无效.

您可以通过传递shared_ptr&lt;thread&gt; 而不是thread* 来修复它:

void insert(boost::shared_ptr<boost::thread>);
void createThread(DerivedInterface& t)

    boost::shared_ptr<boost::thread> t1(new boost::thread(&DerivedInterface::run, &t)); 
    insert(t1);

或者,在 C++11 中使用右值引用:

void insert(boost::thread&& t1);

void createThread(DerivedInterface& t)

    boost::thread t1(&DerivedInterface::run, &t); 
    insert(std::move(t1));

或者,使用为您完成上述操作的boost::thread_group

【讨论】:

只是出于好奇,将 t1 设为 boost::thread* t1 = new boost::thread(...); 然后在解构器中删除所有这些是否也有效? mmm 我的对象 DerviedObject 被其他对象扩展,所以当我创建一个新对象时,我想保持这些对象(线程)的集合,当然也删除所有对象。如果我使用一组线程,我怎样才能中断其中一个?但是,以下指令在我的环境中不起作用: boost::thread* t1 = new boost::thread(...) 但是你是对的,可能我应该使用 shared_ptr 如果我使用一组线程,createThread的逻辑总是不正确,因为超出范围然后失败,但是第二种方式不起作用(insert(std::move(t1 ));) @Prisco 我根本不会使用线程中断,因为确保终止的线程正确清理资源并且不让任何东西处于不一致的状态并非易事。特别是如果您使用 3rd-party 库。 @MaximYegorushkin 你能帮我使用 shared_ptr 吗?像这样的东西? void createThread(DerivedInterface& t) boost::thread t1(&DerivedInterface::run, &t); boost::shared_ptr<:thread> shar = t1;插入(&shar);

以上是关于指向 boost::thread 的指针的主要内容,如果未能解决你的问题,请参考以下文章

boost thread:对象被释放后修改

类内的Boost Thread无法访问成员变量

53 指向指针的指针(多重指针)

如何定义指向函数的指针?

两个指针指向同一个地址,怎样只改变其中的一个指针的内容

C++ 指向指针的指针