shared_ptr <std :: deque>的析构函数问题,作为参数传递给新线程</std :: deque>

时间:2014-05-16 14:13:32

标签: c++ windows multithreading shared-ptr beginthread

我将包含shared_ptrstd::deque的params结构作为函数的输入参数传递,这将在新线程中起作用。此双端队列在外部对象上创建为公共字段。当我将shared_ptr保存到params结构时,shared_ptr中的引用数量会增加,而且一切似乎都没问题。

对于线程,它是在调用_beginthread()函数的帮助下创建的。在线程内部,我将一些值推送到deque,由shared_ptr指向。这些值正确地弹出外部对象,所以一切似乎都没问题。

当线程完成它的工作时,从堆中删除的params结构和ref计数器递减(一切都很好)。但是当创建这个shared_ptr的外部对象的析构函数被调用时,refs计数器递减并等于0,因此实际调用了指向对象的析构函数,并且出现调试断言失败。失败的表达式是_pFirstBlock == pHead(双删除?)。但是我在VS2012的数据断点帮助下查看了shared_ptr._Rep._Uses的地址只能在我上面描述的时刻访问。

还有一点需要注意:如果没有任何东西进入此双端队列,那么所有析构函数都会成功运行。 我做错了什么?

typedef std::deque<MsgBuf_ptr> MsgQueue;
typedef std::tr1::shared_ptr<MsgQueue> MsgQueue_ptr;
typedef const MsgQueue_ptr& MsgQueue_ptr_p;

shared_ptr创建:

...
MsgQueue_ptr qMsgQueue;
...
qMsgQueue.reset(new MsgQueue)
...
bool bStartOK = start(qMsgQueue, ghMutex);  

线程参数结构:

struct ThreadServerParam {  
    HANDLE ghStopEvent;
    MsgQueue_ptr qMsgQueue; 
    HANDLE ghMutex;
};

线程创建:

void start(MsgQueue_ptr_p qMsgQueue, HANDLE ghMutex) {
    param = new ThreadServerParam;
    param->qMsgQueue = qMsgQueue;   
    param->ghStopEvent = ghStopEvent;
    param->ghMutex = ghMutex;

    hThread = (HANDLE)_beginthread( &ThreadFunction, THREAD_STACK_SIZE, param );
    if(hThread == INVALID_HANDLE_VALUE || hThread == NULL) {...}
}

线程功能:

void ThreadFunction(void* ptr) {
    ThreadServerParam *param = (ThreadServerParam*) ptr;    
    while(dwWaitResult != WAIT_OBJECT_0) {          
        findNewMessage(internalQueue);
        if(!msgQueue->empty()) {                
        DWORD dwWaitResult = WaitForSingleObject(param->ghMutex, INFINITE);
        switch (dwWaitResult) {
                case WAIT_OBJECT_0: 
                    while (!msgQueue->empty()) {
                        MsgBuf_ptr msg_buf = internalQueue->front();
                        param->qMsgQueue->push_back(msg_buf);                                   
                        internalQueue->pop_front();
                    }
             ...
            }
          }
          Sleep(GAP);
      dwWaitResult = WaitForSingleObject(param->ghStopEvent, 0);
     }
     delete param;
 }

0 个答案:

没有答案