STL list在多线程下使用需要注意的问题

        最近做一个印刷品缺陷检测的图像处理的项目,是实时处理的。采用了多线程的方式,线程A负责从相机中取数据,线程B负责处理取到的数据。由于相机数据是以固定时间间隔过来,而且不能等待,所以我就想到利用一个双向链表来保存数据,线程A不停地往链表的尾部添加数据,线程B从链表头部取走数据,然后将表头节点pop出去。感觉上这两个线程虽然同时对链表进行操作,但是一个是往尾部追加数据,一个从头部取数据,似乎不会发生冲突,所以也没有加锁。但是运行过程中偶尔会出错,弹出itrator not refrenceable之类的错误。

        我怀疑是由于list并不是线程安全的,所以两个线程同时对list进行操作会应发莫名其妙的问题。于是我写了一个简单的小程序测试一下。

#include "stdafx.h"
#include
#include
#include
#include
using namespace std;
class CBaselock
{
public:
CBaselock()
{
InitializeCriticalSection(&m_Sec);//初始化临界区
}
~CBaselock()
{
DeleteCriticalSection(&m_Sec);
}
void Lock()
{
EnterCriticalSection(&m_Sec);
}
void UnLock()
{
LeaveCriticalSection(&m_Sec);
}
private:
CRITICAL_SECTION m_Sec;
};


class CTestList
{
public:
CTestList() {};
~CTestList() {};
long Start();
static unsigned __stdcall PushThred(void * pThis)
{
CTestList * pthX = (CTestList*)pThis;   // the tricky cast  
pthX->pushFunc();           // now call the true entry-point-function  
return 1;                           // the thread exit code  
}
static unsigned __stdcall PopThred(void * pThis)
{
CTestList * pthX = (CTestList*)pThis;   // the tricky cast  
pthX->popFunc();           // now call the true entry-point-function  
return 1;                           // the thread exit code  
}
long pushFunc();
long popFunc();
list m_list;
CBaselock m_lock;
};


long CTestList::Start()
{
_beginthreadex(NULL, 0, &PushThred, this, 0, 0);
_beginthreadex(NULL, 0, &PopThred, this, 0, 0);
return 1;
}
long CTestList::pushFunc()
{
int index = 0;
while (1)
{
//m_lock.Lock();
printf("push:%d,list size:%d\n", index, m_list.size());
m_list.push_back(index);
//m_lock.UnLock();
++index;
//Sleep(0);
}
return 1;
}
long CTestList::popFunc()
{
while (1)
{
if (m_list.size() > 0)
{
//m_lock.Lock();
printf("pop:%d,list size:%d\n", m_list.front(), m_list.size());
m_list.pop_front();
//m_lock.UnLock();
//Sleep(0);
}
}
return 1;
}


int main()
{
CTestList testObj;
testObj.Start();
int a = 0;
std::cin >> a;
        return 0;
}

在没有加锁时,测试时偶尔会弹出错误,于是老老实实加锁,测试没有报错了。

总结一点,stl list不是线程安全的,在多线程下使用时一定要记得加锁。

你可能感兴趣的:(STL list在多线程下使用需要注意的问题)