我试图找到段错误背后的罪魁祸首。我的调试器告诉我,这个错误所在的变量没有数据。每10秒钟,我的C++代码中会有一个脚本运行。它做了“垃圾收集”并删除了一些可能死亡的“会话”。 为了有效地执行此操作,我使用时间戳 - 上次访问数据的时间。如果数据超过10秒钟,它就已经死了。在客户端上每隔4秒触发一次keepalive命令。std :: unordered_map中可能存在的错误
要执行这个GC,我循环访问一个std :: unordered_map,然后减去从epoch开始的当前时间。如果时间太长,我将它添加到一个std :: vector中,它保存要删除的键(是的,我知道它可以优化来跳过这一步)。
我面临的问题是它第一次正确循环。然而,此后,我得到一个segfault,它指向的迭代器值大于地图的大小。 只需切换回标准的std :: map就可以修复整个问题!
我将附加完成所有这些功能。所有的代码在http://github.com/yash101/DrawingPad
现已上市,代码[{} sourcedir /source/Session.cxx]:
void SessionHost::cron()
{
while(true)
{
std::this_thread::sleep_for(std::chrono::seconds(10));
if(DEBUG)
{
std::cout << "Cron has started!" << std::endl;
}
while(!locky_thingy.try_lock_for(std::chrono::milliseconds(MUTEX_TIMEOUT)))
{}
int timethrough = 0;
std::vector<std::string> del;
for(std::map<std::string, long>::iterator ite = timestamp.begin(); ite != timestamp.end(); ++ite)
{
timethrough++;
std::cout << "Time through: " << timethrough << std::endl;
std::string curkey = ite->first;
long curval = ite->second;
std::cout << "Key: " << curkey << std::endl;
if(DEBUG)
{
std::cout << "Checking " << curkey << " with old ts of " << curval << std::endl;
}
u_int64_t curtm = std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now().time_since_epoch()).count();
if(DEBUG)
{
std::cout << "Current time: " << curtm << std::endl;
}
if(curtm - curval > SESSION_TIMEOUT)
{
if(DEBUG)
{
std::cout << "Deleted session handle: [" << curkey << "]" << std::endl;
}
del.push_back(curkey);
}
else
{
if(DEBUG)
{
std::cout << "Kept back session handle: [" << curkey << "]" << std::endl;
}
}
for(unsigned int i = 0; i < del.size(); i++)
{
timestamp.erase(del[i]);
data.erase(del[i]);
std::cout << "Erasing: " << del[i] << std::endl;
}
}
locky_thingy.unlock();
}
}
std :: map timestamp <==在{sourcedir} /include/Session.hxx –
yash101
2014-11-03 01:57:08
我在这段代码中看不到'unordered_map' – Barry 2014-11-03 02:00:00
你在做什么并行?确保在更新地图时没有数据竞争,因为这会使迭代器无效,因为您共享数据。否则,使用'std :: begin'和'std :: end'的'std :: unordered_map'应该总是有效。 – vsoftco 2014-11-03 02:03:43