为了优化散列表中的清除项目,我使用了read_lock,后跟write_lock:
DEFINE_RWLOCK(ht_rwlock);
void Clear(void (*deleter)(const void*))
{
int i;
struct hash_table* temp_node;
read_lock(&ht_rwlock);
hash_for_each(spu_hash_table, i, temp_node, next)
{
write_lock(&ht_rwlock);
hash_del(&temp_node->next);
write_unlock(&ht_rwlock);
deleter((const void*)temp_node);
}
read_unlock(&ht_rwlock);
}
然而,这给了我一个错误: 内核:BUG:软锁定 - CPU#0卡住22秒! [rmmod的:6724]
使用write_lock / write_unlock的非优化版本只能正常工作:
void Clear(void (*deleter)(const void*))
{
int i;
struct hash_table* temp_node;
write_lock(&ht_rwlock);
hash_for_each(spu_hash_table, i, temp_node, next)
{
hash_del(&temp_node->next);
deleter((const void*)temp_node);
}
write_unlock(&ht_rwlock);
}
我的问题是我真的必须使用写锁来迭代哈希表吗?
答案 0 :(得分:1)
我的问题是我真的必须使用写锁来迭代哈希表吗?
是。内核中的RWlock不支持从读锁定到写锁定的转换。
原因很简单:有两个进程,每个进程都处于读取部分,并希望将其提前写入一个进程,导致死锁。
但是你的情况是纯修改一个(你删除了列表中的所有元素),所以使用read_lock将其转换为写锁定无论如何都不会获得性能。使用write_lock
,与第二段代码一样。
如果您关心性能,请考虑使用RCU锁 - 它允许读写器同时运行,因此根本不需要rwlock
,同步编写器的简单lock
就足够了。但是RCU的装置取决于背景。