当前位置: 代码迷 >> 多核软件开发 >> 线程同步与队列的使用有关问题
  详细解决方案

线程同步与队列的使用有关问题

热度:9876   发布时间:2013-02-26 00:00:00.0
线程同步与队列的使用问题 - C/C++ / C++ 语言
大家好,我写了一个程序:
  一个类的声明如下:
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();都包括进去
------解决方案--------------------------------------------------------
探讨

while(!mdrQ.empty())
试试改为if(!mdrQ.empty())
{}
else
bContinue = FALSE;

------解决方案--------------------------------------------------------
多线程中涉及到STL的东西都应该做同步处理。
------解决方案--------------------------------------------------------
我个人觉得 
MediaInfo mediaInfo=mdrQ.front();
  相关解决方案