大家好,我写了一个程序:
一个类的声明如下:
class MediaInfo
{
private:
BYTE *pd;
media_data_rec *pm;
int n;
public:
MediaInfo(int len, int vid, int aid, BYTE *buffer, int handle);
MediaInfo(const MediaInfo &m);
~MediaInfo();
media_data_rec getMdr() const;
int getHandle() const;
BYTE * getData() const;
};
然后定义了全局变量:
queue<MediaInfo> mdrQ;
CRITICAL_SECTION CriticalSection;
HANDLE ghSemaphore;
之后初始化了信号量和临界区:
ghSemaphore = CreateSemaphore( NULL, 0, 1000000, NULL);
if (ghSemaphore == NULL)
{
printf("CreateSemaphore error: %d\n", GetLastError());
return 1;
}
if (!InitializeCriticalSectionAndSpinCount(&CriticalSection,
0x00000400) )
return -1;
之后写了创建了一个线程,不断把信息放到队列mdrQ,其调用的函数是:
void CALLBACK lll(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, void* pUser)
{
MediaInfo * pmi = NULL;
if (SN_DVR_STREAMDATA == dwDataType)
{
MediaInfo * pmi = new MediaInfo(dwBufSize, 0, 0, pBuffer, n);
if(!pmi)
{
writeLog("new","lll pmi");
exit(-1);
}
EnterCriticalSection(&CriticalSection);
mdrQ.push(*pmi);
LeaveCriticalSection(&CriticalSection);
//发出信号量,通知另一个线程,mdrQ有数据可以上传
if (!ReleaseSemaphore(ghSemaphore, 1, NULL) )
{
printf("ReleaseSemaphore error: %d\n", GetLastError());
}
printf("Data length:%d \n", dwBufSize);
}
之后创建了另一个一个线程不停地从队列mdrQ得到信息上传,其调用的函数是:
DWORD WINAPI UpLoad( LPVOID lpParam )
{
DWORD dwWaitResult;
BOOL bContinue=TRUE;
int n, i=0, dwBufSize,j = 24;
BYTE * pBuffer = NULL;
while(bContinue)
{
//等待信号量
dwWaitResult = WaitForSingleObject(
ghSemaphore, // handle to semaphore
INFINITE); // zero-second time-out interval
if (WAIT_OBJECT_0 == dwWaitResult)
{
while(!mdrQ.empty())
{
MediaInfo mediaInfo=mdrQ.front();
media_data_rec mdr=mediaInfo.getMdr();
n=mediaInfo.getHandle();
g_module_info.ev_callbcak(g_module_info.module_handle,n,EV_MEDIA,(char*)&mdr,mdr.datalen); //上传数据
EnterCriticalSection(&CriticalSection);
mdrQ.pop();
LeaveCriticalSection(&CriticalSection);
}
}
}
return TRUE;
}
请问为什么程序运行到一定时间之后,就会出现"Debug Assertion Failed! Expression: deque iterator not dereferencable "出错呢?
我参考了相应资料,推测可能是mdrQ的操作问题引起的。但是对于“mdrQ.push(*pmi);”和“mdrQ.pop();”已经做了判断mdrQ是否为空,并且写了临界区(CriticalSection)的保护,为什么还会出问题呢?
谢谢大家的指点!
------解决方案--------------------------------------------------------
线程安全一类的问题也许没有那么容易遇到。
据我经验看,你也就是STL的用法没有保护好,没事用empty试一试。。。能不能pop啊什么的。
------解决方案--------------------------------------------------------
while(!mdrQ.empty())
试试改为if(!mdrQ.empty())
{}
else
bContinue = FALSE;
------解决方案--------------------------------------------------------
UpLoad函数里面的临界区操作你必须将mdrQ.front();都包括进去
------解决方案--------------------------------------------------------
------解决方案--------------------------------------------------------
多线程中涉及到STL的东西都应该做同步处理。
------解决方案--------------------------------------------------------
我个人觉得
MediaInfo mediaInfo=mdrQ.front();