求助: 使用map导致排版错乱问题

DontKissBossAss 2010-12-06 10:22:57
程序在后来一次设计的时候使用了map存储key- Value对, 但是运行一段时间以后,出现错误。



比如,正常情况下

程序输出的顺序应该是1,2,3,4,5,6,7,8
但是在程序运行一段时间之后,出现了 2,3,1,8,7,5,6,4 等无规律顺序错乱、乱码问题

程序代码中一个线程写读map,令一个线程读map。

CcriticalSection g_cs;
线程1:写map
for(int i = 0; i < m_vectorSelectIndex.size(); i ++)
{
string str;
int nkey = m_vectorSelectIndex[i];
//dealwith str;
g_cs.lock()
m_mapFrameInfoValue[nkey] = str;
g_cs.unlock();
}
for (int i = 0; i < m_vectorSelectIndex.size(); i++)
{
string strValue = "";
int nKey = m_vectorSelectIndex[i];
strValue = GetMapFrameData(nKey);
if (strValue.empty())
{
strValue = "0";
}
WriteFile(strValue.c_str(), false); //把str写进文件
WriteFile(" ", false);
}

//令一个线程中
for (int i = 0; i < m_vectorSelectIndex.size(); i++)
{
string strValue = _T("");
int nKey = m_vectorSelectIndex[i];
strValue = GetMapFrameData(nKey);
if (strValue.empty())
{
continue;
}
m_pMyTest->m_pTestListCtrl->SetItemText(m_nRawIndexInListBox, i + 1, strValue.c_str());
}
//GetMapFrameData 的实现
string CDevice::GetMapFrameData(int nKey)
{
string strValue;
g_cs.Lock();
map<int, string>::iterator it = m_mapFrameInfoValue.find(nKey);
if (it == m_mapFrameInfoValue.end())
{
g_cs.Unlock();
return string("");
}
strValue = (*it).second;
g_cs.Unlock();
return strValue;
}
...全文
267 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
太乙 2010-12-06
  • 打赏
  • 举报
回复
我不知道lz打印的是什么,怎么打印的。

但是看上去,锁是没有问题的,

lz在打印的时候,可能存在一个问题,就是挨个打印,虽然对每个数字的输出是有加锁的,但是对整体的输出没有加锁,导致,在某一个数字输出之后,其他数字发生改变,而下次输出,导致整个序列不是先前的那个序列。。。

不知道我说明白没?
DontKissBossAss 2010-12-06
  • 打赏
  • 举报
回复
高手拿拿注意呗,我这代码已经加锁了,只是在单独单写的时候加的,存在读写混合的情况。

我现在唯一的想法就是和7楼 12楼一样,把整个写的过程加锁,防止打断
DontKissBossAss 2010-12-06
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 luciferisnotsatan 的回复:]
加个锁就是了
记得编译器也会提供一个多线程安全的标准库。可以用那个
[/Quote]

关键是上边代码加锁了啊。我现在就是纠结,锁加错了?
luciferisnotsatan 2010-12-06
  • 打赏
  • 举报
回复
加个锁就是了
记得编译器也会提供一个多线程安全的标准库。可以用那个
DontKissBossAss 2010-12-06
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 hairetz 的回复:]
对于非自定义类型,都不要认为是线程安全的。就连 string都不是线程安全,多线程不加限制使用,可能会崩溃。

http://blog.vckbase.com/wangjun/archive/2005/07/01/9062.aspx

所以,你多线程操作map,请加锁。
[/Quote]

我理解你连接里面的代码,如果没有加锁,string:: = 操作的时候,可能引起string因为了未定义的内存。出错。
DontKissBossAss 2010-12-06
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 qq120848369 的回复:]
加个锁就是了,有什么可研究的.
[/Quote]

关键是上边已经加锁了
qq120848369 2010-12-06
  • 打赏
  • 举报
回复
加个锁就是了,有什么可研究的.
DontKissBossAss 2010-12-06
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 hairetz 的回复:]
对于非自定义类型,都不要认为是线程安全的。就连 string都不是线程安全,多线程不加限制使用,可能会崩溃。

http://blog.vckbase.com/wangjun/archive/2005/07/01/9062.aspx

所以,你多线程操作map,请加锁。
[/Quote]

高手认同7楼和12楼的说法么
DontKissBossAss 2010-12-06
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 hairetz 的回复:]
对于非自定义类型,都不要认为是线程安全的。就连 string都不是线程安全,多线程不加限制使用,可能会崩溃。

http://blog.vckbase.com/wangjun/archive/2005/07/01/9062.aspx

所以,你多线程操作map,请加锁。
[/Quote]

运行了那个例子,但是没发现问题啊。。。,使用深copy,但是 这是编译器对string的需要,我怎么控制呢
就想叫yoko 2010-12-06
  • 打赏
  • 举报
回复
刚才写的有点问题,解锁也要放在for循环外面
  • 打赏
  • 举报
回复
对于非自定义类型,都不要认为是线程安全的。就连 string都不是线程安全,多线程不加限制使用,可能会崩溃。

http://blog.vckbase.com/wangjun/archive/2005/07/01/9062.aspx

所以,你多线程操作map,请加锁。
DontKissBossAss 2010-12-06
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 pengzhixi 的回复:]
读的时候也加锁看看吧
[/Quote]

可恶的CSDN, 打开页面只要不到1s的时间,但是,打开恢复内容那块的区域居然要N长时间。


读的时候有锁的,读是通过函数GetMapFrameData实现的。读写用的都是同一个锁。
现在看来7 8楼说的又点道理,我打算按照7楼的意见试试,把整个写的过程加锁,防止打断
cunyan_0519 2010-12-06
  • 打赏
  • 举报
回复
不明白哦,帮你顶上去,等牛人解决吧!!!
gules 2010-12-06
  • 打赏
  • 举报
回复
出现这种情况,一般都是与加锁错误有关系,对临界区边界没有定义清楚。
就想叫yoko 2010-12-06
  • 打赏
  • 举报
回复
for(int i = 0; i < m_vectorSelectIndex.size(); i ++)
{
string str;
int nkey = m_vectorSelectIndex[i];
//dealwith str;
g_cs.lock()
m_mapFrameInfoValue[nkey] = str;
g_cs.unlock();
}

修改为
g_cs.lock();
for(int i = 0; i < m_vectorSelectIndex.size(); i ++)
{
string str;
int nkey = m_vectorSelectIndex[i];
//dealwith str;
//g_cs.lock()
m_mapFrameInfoValue[nkey] = str;
g_cs.unlock();
}

试试看
就想叫yoko 2010-12-06
  • 打赏
  • 举报
回复
for(int i = 0; i < m_vectorSelectIndex.size(); i ++)
{
string str;
int nkey = m_vectorSelectIndex[i];
//dealwith str;
g_cs.lock()
m_mapFrameInfoValue[nkey] = str;
g_cs.unlock();
}

修改为
g_cs.lock();
for(int i = 0; i < m_vectorSelectIndex.size(); i ++)
{
string str;
int nkey = m_vectorSelectIndex[i];
//dealwith str;
//g_cs.lock()
m_mapFrameInfoValue[nkey] = str;
g_cs.unlock();
}

试试看
pengzhixi 2010-12-06
  • 打赏
  • 举报
回复
读的时候也加锁看看吧
DontKissBossAss 2010-12-06
  • 打赏
  • 举报
回复
首先 m_vectorSelectIndex 是只读类型的,其他地方都没有修改,

其次: 文件内顺序是乱的,UI没看到程序崩溃了
文件时在线程1完成的

它是先写,在读,看线程1代码。

但是为什么刚开始好好的,跑一段时间之后给崩溃了呢
DontKissBossAss 2010-12-06
  • 打赏
  • 举报
回复
首先 m_vectorSelectIndex 是只读类型的,其他地方都没有修改,

其次: 文件内顺序是乱的,UI没看到程序崩溃了
文件时在线程1完成的

它是先写,在读,看线程1代码。

但是为什么刚开始好好的,跑一段时间之后给崩溃了呢
DontKissBossAss 2010-12-06
  • 打赏
  • 举报
回复
首先 m_vectorSelectIndex 是只读类型的,其他地方都没有修改,

其次: 文件内顺序是乱的,UI没看到程序崩溃了
文件时在线程1完成的

它是先写,在读,看线程1代码。

但是为什么刚开始好好的,跑一段时间之后给崩溃了呢
加载更多回复(7)

64,282

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧