Я передаю структуру params, которая содержит shared_ptr
в std::deque
, в качестве входного аргумента для функции, которая будет работать в новом потоке. Эта дека создана на внешнем объекте как публичное поле. И когда я сохраняю shared_ptr в params
структура, число ссылок в shared_ptr увеличивается, и все, кажется, в порядке.
Что касается потока, он создается с помощью вызова _beginthread()
функция. Внутри потока я помещаю некоторые значения в deque, на которые указывает shared_ptr. Эти значения корректно отображаются на внешнем объекте, поэтому, похоже, все снова в порядке.
Когда поток завершает свою работу, структура параметров удаляется из кучи, а счетчик ссылок уменьшается (все снова в порядке). Но когда вызывается деструктор внешнего объекта, где был создан этот 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;
}
Задача ещё не решена.