我正在编写一个程序,其中多个线程将条目添加到(tbb :: concurrent_hash_map)哈希映射,同时其他线程遍历此映射并操纵哈希映射上的条目。每次一个线程操作并使用一个条目并使用访问器阻止此条目(这样就不会发生冲突,其他线程也无法访问此条目)。操作数据后,线程插入数据并释放访问者。
我现在的问题是线程如何访问被阻止的条目,直到该条目的访问者被释放,即使哈希映射上的其他条目未被阻止。我想要实现的目标是,线程跳过被阻止的条目并转到下一个非阻塞条目或返回到我的函数。它有一个很好的解决方案吗?
以下代码片段为短单线程示例:
...
typdef tbb::concurrent_hash_map<int,unsigned int> typ_hash_map;
typ_hash_map hash_map;
typ_hash_map::accessor acc;
typ_hash_map::accessor acc2;
//hash_map filled with 4 entries...
//block second entry in hash map
typ_hash_map::iterator k = hash_map.begin();
k++;
config.hash_map.insert(acc,k->first);
//travers all entries in hash_map
for(typ_hash_map::iterator j = hash_map.begin();j!=hash_map.end(); j++){
hash_map.find(acc2,j->first); // my problem: return if entry is blocked - at the moment its waiting till acc is released
/*
Do something with acc2->second if entry is not blocked,
else continue;
*/
}
...
答案 0 :(得分:0)
您是否知道遍历tbb::concurrent_hash_map
不是线程安全的?如果您的代码是串行代码,则无需保护:因此,您无需持有访问者。
在任何情况下,长时间锁定元素都是一个坏主意,因为它会损害可伸缩性并导致像您这样的死锁,应该在更新完成或读取数据后立即释放。
concurrent_hash_map的一般规则是:不要在持有第一个任务的情况下对其他访问者运行任何哈希表操作。
因此,只需在完成后立即释放访问者acc
:acc.release()