0

shared_ptrtoを含む params 構造体std::dequeを関数の入力引数として渡します。これは新しいスレッドで機能します。この両端キューは、パブリック フィールドとして外部オブジェクトに作成されます。そして、shared_ptr をparams構造体に保存すると、shared_ptr の参照数が増加し、すべて問題ないようです。

スレッドに関しては、呼び出し_beginthread()関数を使用して作成されます。スレッド内で、shared_ptr が指すいくつかの値を deque にプッシュします。これらの値は外部オブジェクトで正しくポップされるため、すべてが再び問題ないように見えます。

スレッドが作業を終了すると、params 構造体がヒープから削除され、ref カウンターが減少します (すべて問題ありません)。しかし、この shared_ptr が作成された外部オブジェクトのデストラクタが呼び出されると、refs カウンターがデクリメントされて 0 になるため、実際にポイントされたオブジェクトのデストラクタが呼び出され、デバッグ アサーション エラーが表示されます。失敗した式は _pFirstBlock == pHead (二重削除?) です。しかし、VS2012 のデータ ブレークポイントの助けを借りて確認しました。そのアドレスは、shared_ptr._Rep._Uses上記の瞬間にのみアクセスされます。

もう 1 つ注意: この両端キューに何もプッシュされない場合、すべてのデストラクタが正常に実行されます。私が間違っていることは何ですか?

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;
 }
4

0 に答える 0