我有一个多线程应用程序,它使用 C++ STL hash_map
来存储键值对。 hash_map
定义如下:
struct eqstr
{
bool operator()(const string& s1, const string& s2) const
{
return (s1 == s2);
}
};
typedef hash_map<string,UserData, hash<string>, eqstr> DataMap;
DataMap datamap;
其中,UserData 是一个简单的结构类型,具有
struct UserData
{
char id[4+1];
char date[20+1];
int mode;
};
在我的申请中,我有
bool found = true;
pthread_mutex_lock(&muCS);
DataMap::iterator itr;
itr = datamap.find(key); // key is a string
if (itr == datamap.end())
found = false;
pthread_mutex_unlock(&muCS);
当应用程序运行时,我偶尔会崩溃,pstack core 显示如下:
--- called from signal handler with signal 11 (SIGSEGV) ---
ff31db18 assign__t18string_char_traits1ZcRcRCc (fc07b958, 877f48, 877f58, 2, 1, 662fc0) + 8
00263f24 c_str__Ct12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0 (fc07b958, 83af88, fc07b0c8, 1a, ffbff778, fffc00) + 34
00346c34 __cl__Ct4hash1Zt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0RCt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0 (77fd59, fc07b958, ffffffff, fc07b0c8, 1a, 80808080) + 18
00346900 _M_bkt_num_key__Ct9hashtable6Zt4pair2ZCt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0Z8UserDataZt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0Zt4hash1Zt12basic_string3ZcZt18strin (77fd58, fc07b958, c005, fc07b0e2, 1, 1) + 1c
00346960 _M_bkt_num_key__Ct9hashtable6Zt4pair2ZCt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0Z8UserDataZt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0Zt4hash1Zt12basic_string3ZcZt18strin (77fd58, fc07b958, cc, fc551200, ff2c2030, 10000) + 28
00347140 find__t9hashtable6Zt4pair2ZCt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0Z8UserDataZt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0Zt4hash1Zt12basic_string3ZcZt18string_char_trai (77fd58, fc07b958, fc551a00, 6633d0, 2922e4, 6633d8) + 18
003469f0 find__t8hash_map5Zt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0Z8UserDataZt4hash1Zt12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0Z5eqstrZt9allocator1Z8UserDataRCt12basic_s (77fd58, fc07b958, fc07b910, 0, 6633d0, 26a0bc) + 1c
因此,在 hash_map
中查找 STL 字符串似乎失败了。
我有带信号量的标准守卫以确保互斥。
会出什么问题?
任何补救建议或任何解决方法都会有很大帮助。您是否觉得 hash_map
需要更改为一些更好的数据结构或任何其他解决方法以防止 STL 字符串崩溃?
提前致谢。
最佳答案
我将执行以下操作来修复崩溃:
- 如果您没有 c++11,请将
hash_map
更改为std::map
,或者更改为std::unordered_map
。 - 如果您有 c++11,请使用
std::mutex
和std::unique_lock
而不是pthread_*
函数。pthread_mutex_lock
这里有两个问题:它们不是异常安全的(如果在pthread_mutex_lock
和pthread_mutex_unlock
之间会产生一些异常,mutex 永远不会解锁,你会遇到死锁),并且你不检查这个函数的返回值(如果你的互斥量不能被锁定,或者没有正确初始化,你永远不会知道,错误将被默默地忽略,你会得到数据竞赛)。 - 检查是否在
pthread_mutex_unlock
方法之后使用了itr
。即使搜索操作已完成,您仍然可以进行数据竞争,因为不同的线程可以尝试更新迭代器指向的值。所以这个操作也应该受到互斥锁的保护。 - 检查您的 map 的所有访问是否都受到一个互斥体的保护。如果您发现它无效,之后您可以随时更改锁类型(例如读/写锁)或为每个
UserData
添加一个锁。 - 检查您的代码设计。将您的 map 容器添加到一个类中并将其设为私有(private)。这样您就可以控制对它的访问。向此类添加一个互斥锁,然后在访问映射之前,只需检查该类的所有公共(public)方法中的互斥锁是否已锁定一次。
如果有帮助,请回信。
关于c++ - 尝试在 hash_map 中查找记录时应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22197915/