加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

并发性 – 特定场景的最佳Linux内核锁定机制是什么

发布时间:2020-12-26 14:31:23 所属栏目:Linux 来源:网络整理
导读:我需要为这种情况解决锁定问题: 多CPU系统. 所有CPU都使用通用(软件)资源. 只读访问资源非常常见. (传入网络数据包的处理) 写访问频率低得多. (仅限配置更改). 目前我使用read_lock_bh,write_lock_bh(自旋锁)机制. 问题是CPU越多,我在编写器上下文中获得

我需要为这种情况解决锁定问题:

>多CPU系统.
>所有CPU都使用通用(软件)资源.
>只读访问资源非常常见. (传入网络数据包的处理)
>写访问频率低得多. (仅限配置更改).

目前我使用read_lock_bh,write_lock_bh(自旋锁)机制.
问题是CPU越多,我在编写器上下文中获得的软锁定就越多.

我在this book阅读了并发章节,
但是在使用自旋锁时,无法理解读者或作者是否会获得优先权.

所以问题是:

> Linux自旋锁机制是否优先考虑读者/作者/没有?
>我可以使用更好的机制来避免在我的场景中出现那些软锁定,或者在使用我当前的解决方案时,可能是我在尝试获取锁定时优先考虑编写器的方法吗?

谢谢,
尼尔

解决方法

这是 Essential Linux Device Drivers的直接引用,可能是您正在寻找的.似乎最后处理RCU的部分可能是你感兴趣的部分.

读者 – 作家锁

另一种专门的并发调节机制是自旋锁的读写器变体.如果使用一个
关键部分是这样的,即单独的线程可以读取或写入共享数据结构,但不能这样做
两者,这些锁都很自然.允许多个读取器线程同时在关键区域内.
Reader自旋锁的定义如下:

rwlock_t myrwlock = RW_LOCK_UNLOCKED;

read_lock(&myrwlock);             /* Acquire reader lock */
/* ... Critical Region ... */
read_unlock(&myrwlock);           /* Release lock */

但是,如果编写器线程进入临界区,则不允许其他读取器或写入器线程进入.使用
写作者自旋锁,你会写这个:

rwlock_t myrwlock = RW_LOCK_UNLOCKED;

write_lock(&myrwlock);            /* Acquire writer lock */
/* ... Critical Region ... */
write_unlock(&myrwlock); /* Release lock */

查看net / ipx / ipx_route.c中的IPX路由代码,了解读写器自旋锁的实际示例.一个
名为ipx_routes_lock的读写器锁可以保护IPX路由表不被同时访问.主题
需要查找路由表以转发数据包请求读取器锁.需要添加或的线程
从路由表中删除条目获取编写器锁.这通常会提高性能
路由表查找的实例远多于路由表更新.

像常规自旋锁一样,读写器锁也有相应的irq变体 – 即read_lock_irqsave(),
read_lock_irqrestore(),write_lock_irqsave()和write_lock_irqrestore().这些语义
函数类似于常规自旋锁的函数.

2.6内核中引入的序列锁或序列锁是读写器锁,其中编写器受到青睐
读者.如果对远远超出读取的变量进行写操作,则此操作非常有用.一个例子是
本章前面讨论过的jiffies_64变量.作家线程不等待可能在里面的读者
一个关键部分.因此,读者线程可能会发现他们在关键部分内的输入失败了
并可能需要重试:

u64 get_jiffies_64(void) /* Defined in kernel/time.c */
{
   unsigned long seq;
   u64 ret;
   do {
      seq = read_seqbegin(&xtime_lock);
      ret = jiffies_64;
   } while (read_seqretry(&xtime_lock,seq));
   return ret;
}

编写器使用write_seqlock()和write_sequnlock()保护关键区域.

2.6内核引入了另一种称为读取副本更新(RCU)的机制,它产生了改进
当读者远远超过作家时的表现.基本思想是读者线程可以在没有的情况下执行
锁定.编写器线程更复杂.它们对数据结构的副本执行更新操作
替换读者看到的指针.保留原始副本,直到所有CPU上的下一个上下文切换为
确保完成所有正在进行的读取操作.请注意,使用RCU比使用RCU更复杂
到目前为止讨论的原语只有在你确定它是正确的工具时才应该使用. RCU数据
结构和接口函数在include / linux / rcupdate.h中定义.有充足的文档
文档/ RCU / *.

有关RCU用法示例,请查看fs / dcache.c.在Linux上,每个文件都与目录条目相关联信息(存储在称为dentry的结构中),元数据信息(存储在inode中)和实际数据(存储在数据块中).每次操作文件时,都会解析文件路径中的组件,并且获得相应的dentry. dentries保存在名为dcache,to的数据结构中加快未来的运营.在任何时候,dcache查找的数量远远超过dcache更新,因此使用RCU原语保护对dcache的引用.

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读