{`sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/locking/spinlocksmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/zh_TW/locking/spinlocksmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/it_IT/locking/spinlocksmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/ja_JP/locking/spinlocksmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/ko_KR/locking/spinlocksmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/sp_SP/locking/spinlocksmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageChinese (Simplified)uh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhR/var/lib/git/docbuild/linux/Documentation/translations/zh_CN/locking/spinlocks.rsthKubhnote)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]h paragraph)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hh5Documentation/translations/zh_CN/disclaimer-zh_CN.rsthKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhKubh field_body)}(h$Documentation/locking/spinlocks.rst h]h)}(h#Documentation/locking/spinlocks.rsth]h#Documentation/locking/spinlocks.rst}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h翻译h]h翻译}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhKubh)}(h.唐艺舟 Tang Yizhou h]h)}(h-唐艺舟 Tang Yizhou h](h唐艺舟 Tang Yizhou <}(hj hhhNhNubh reference)}(htangyeechou@gmail.comh]htangyeechou@gmail.com}(hj*hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:tangyeechou@gmail.comuh1j(hj ubh>}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhj ubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhsection)}(hhh](htitle)}(h加锁的教训h]h加锁的教训}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1j[hjXhhhhhK ubjW)}(hhh](j\)}(h教训 1:自旋锁h]h教训 1:自旋锁}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1j[hjkhhhhhKubh)}(h4加锁最基本的原语是自旋锁(spinlock)::h]h3加锁最基本的原语是自旋锁(spinlock):}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjkhhubh literal_block)}(hstatic DEFINE_SPINLOCK(xxx_lock); unsigned long flags; spin_lock_irqsave(&xxx_lock, flags); ... 这里是临界区 .. spin_unlock_irqrestore(&xxx_lock, flags);h]hstatic DEFINE_SPINLOCK(xxx_lock); unsigned long flags; spin_lock_irqsave(&xxx_lock, flags); ... 这里是临界区 .. spin_unlock_irqrestore(&xxx_lock, flags);}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjkhhubh)}(hXR上述代码总是安全的。自旋锁将在 _本地_ 禁用中断,但它本身将保证全局锁定。所以它 将保证在该锁保护的区域内只有一个控制线程。即使在单处理器(UP)下也能很好的工作, 所以代码 _不_ 需要担心UP还是SMP的问题:自旋锁在两种情况下都能正常工作。h]hXR上述代码总是安全的。自旋锁将在 _本地_ 禁用中断,但它本身将保证全局锁定。所以它 将保证在该锁保护的区域内只有一个控制线程。即使在单处理器(UP)下也能很好的工作, 所以代码 _不_ 需要担心UP还是SMP的问题:自旋锁在两种情况下都能正常工作。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjkhhubh block_quote)}(h注意!自旋锁对内存的潜在影响由下述文档进一步描述: Documentation/memory-barriers.txt (5) ACQUIRE operations. (6) RELEASE operations. h](h)}(hK注意!自旋锁对内存的潜在影响由下述文档进一步描述:h]hK注意!自旋锁对内存的潜在影响由下述文档进一步描述:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubj)}(hXDocumentation/memory-barriers.txt (5) ACQUIRE operations. (6) RELEASE operations. h](h)}(h!Documentation/memory-barriers.txth]h!Documentation/memory-barriers.txt}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK!hjubj)}(h1(5) ACQUIRE operations. (6) RELEASE operations. h]henumerated_list)}(hhh](h list_item)}(hACQUIRE operations. h]h)}(hACQUIRE operations.h]hACQUIRE operations.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK#hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hRELEASE operations. h]h)}(hRELEASE operations.h]hRELEASE operations.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK%hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]enumtypearabicprefix(suffix)startKuh1jhjubah}(h]h ]h"]h$]h&]uh1jhhhK#hjubeh}(h]h ]h"]h$]h&]uh1jhhhK!hjubeh}(h]h ]h"]h$]h&]uh1jhhhKhjkhhubh)}(hXO上述代码通常非常简单(对大部分情况,你通常需要并且只希望有一个自旋锁——使用多个 自旋锁会使事情变得更复杂,甚至更慢,而且通常仅仅在你 **理解的** 序列有被拆分的 需求时才值得这么做:如果你不确定的话,请不惜一切代价避免这样做)。h](h上述代码通常非常简单(对大部分情况,你通常需要并且只希望有一个自旋锁——使用多个 自旋锁会使事情变得更复杂,甚至更慢,而且通常仅仅在你 }(hj(hhhNhNubhstrong)}(h **理解的**h]h 理解的}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1j0hj(ubhz 序列有被拆分的 需求时才值得这么做:如果你不确定的话,请不惜一切代价避免这样做)。}(hj(hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK'hjkhhubh)}(hX这是关于自旋锁的唯一真正困难的部分:一旦你开始使用自旋锁,它们往往会扩展到你以前 可能没有注意到的领域,因为你必须确保自旋锁正确地保护共享数据结构 **每一处** 被 使用的地方。自旋锁是最容易被添加到完全独立于其它代码的地方(例如,没有人访问的 内部驱动数据结构)的。h](h这是关于自旋锁的唯一真正困难的部分:一旦你开始使用自旋锁,它们往往会扩展到你以前 可能没有注意到的领域,因为你必须确保自旋锁正确地保护共享数据结构 }(hjJhhhNhNubj1)}(h **每一处**h]h 每一处}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1j0hjJubh 被 使用的地方。自旋锁是最容易被添加到完全独立于其它代码的地方(例如,没有人访问的 内部驱动数据结构)的。}(hjJhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK+hjkhhubj)}(h注意!仅当你在跨CPU核访问时使用 **同一把** 自旋锁,对它的使用才是安全的。 这意味着所有访问共享变量的代码必须对它们想使用的自旋锁达成一致。 h]h)}(h注意!仅当你在跨CPU核访问时使用 **同一把** 自旋锁,对它的使用才是安全的。 这意味着所有访问共享变量的代码必须对它们想使用的自旋锁达成一致。h](h.注意!仅当你在跨CPU核访问时使用 }(hjnhhhNhNubj1)}(h **同一把**h]h 同一把}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1j0hjnubh 自旋锁,对它的使用才是安全的。 这意味着所有访问共享变量的代码必须对它们想使用的自旋锁达成一致。}(hjnhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK0hjjubah}(h]h ]h"]h$]h&]uh1jhhhK0hjkhhubeh}(h]id2ah ]h"]教训 1:自旋锁ah$]h&]uh1jVhjXhhhhhKubh transition)}(h----h]h}(h]h ]h"]h$]h&]uh1jhhhK3hjXhhubjW)}(hhh](j\)}(h教训 2:读-写自旋锁h]h教训 2:读-写自旋锁}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j[hjhhhhhK6ubh)}(hX如果你的数据访问有一个非常自然的模式,倾向于从共享变量中读取数据,读-写自旋锁 (rw_lock)有时是有用的。它们允许多个读者同时出现在同一个临界区,但是如果有人想 改变变量,它必须获得一个独占的写锁。h]hX如果你的数据访问有一个非常自然的模式,倾向于从共享变量中读取数据,读-写自旋锁 (rw_lock)有时是有用的。它们允许多个读者同时出现在同一个临界区,但是如果有人想 改变变量,它必须获得一个独占的写锁。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK8hjhhubj)}(h注意!读-写自旋锁比原始自旋锁需要更多的原子内存操作。除非读者的临界区很长, 否则你最好只使用原始自旋锁。 h]h)}(h注意!读-写自旋锁比原始自旋锁需要更多的原子内存操作。除非读者的临界区很长, 否则你最好只使用原始自旋锁。h]h注意!读-写自旋锁比原始自旋锁需要更多的原子内存操作。除非读者的临界区很长, 否则你最好只使用原始自旋锁。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKEnumerated list start value not ordinal-1: “5” (ordinal 5)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcehlineK uh1jhjubatransform_messages] transformerN include_log]6Documentation/translations/zh_CN/locking/spinlocks.rst(NNNNta decorationNhhub.