您的位置:首页 > 其它

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

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

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

#include "stdafx.h"

#include<iostream>

#include<process.h>

#include<windows.h>

#include<list>

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<int> 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不是线程安全的,在多线程下使用时一定要记得加锁。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: