2014-03-05 64 views
0

我有一个多线程应用程序,它使用C++ STL hash_map来存储键值对。该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核心显示如下:

--- 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字符串崩溃? 在此先感谢。

+0

为什么hash_map而不是一个正常的地图? – Michael

+0

@Michael有O(1)插入期间使用散列,你觉得映射会更好,更安全 –

+0

好hash_map不是标准库的一部分,我至少会尝试unordered_map(只有C++ 11 ) – Michael

回答

1

我会做如下修正崩溃:

  1. 变化hash_map要么std::map如果您有没有C++ 11,或者std::unordered_map
  2. 如果您有C++ 11,请使用std::mutexstd::unique_lock而不是pthread_*函数。这里有pthread_mutex_lock这两个问题:它们不是异常安全的(如果在pthread_mutex_lockpthread_mutex_unlock之间会产生一些异常,互斥将永远不会被解锁,你将会遇到死锁),并且你不检查这个函数的返回值(如果你互斥锁不能被锁定,或者没有正确初始化,你永远不会知道,错误将被默默地忽略,你会得到一个数据竞赛)。
  3. 检查您是否在pthread_mutex_unlock方法后使用itr。即使搜索操作已完成,仍然可以获得数据竞争,导致不同的线程可能会尝试更新迭代器指向的值。所以这个操作也应该被互斥锁保护。
  4. 检查您的地图的所有访问是否受到一个互斥体的保护。如果你发现它不是有效的,你可以随时改变锁的类型(例如读/写锁)或者按照UserData添加一个锁。
  5. 检查您的代码设计。将你的地图容器添加到一个类中,并将其私人化。这样你就可以控制对它的访问。给这个类添加一个互斥锁,然后只要检查该互斥锁是否在该类的所有公共方法中被锁定一次,即访问该地图。

请回复,如果有帮助与否。

+0

非常感谢。由于没有迁移到C++ 11,现在使用std :: map获得更好的结果,至少不像以前那样崩溃。在互斥体解锁后不使用itr,所有对映射的访问都在类中,并且使用一个互斥体进行保护,这包括保护映射中的所有数据访问以确保相互排斥。 –

+0

@DebasishJana很高兴知道它以某种方式帮助你。 –

相关问题