<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=Synchronization_Primitives</id>
	<title>Synchronization Primitives - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=Synchronization_Primitives"/>
	<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Synchronization_Primitives&amp;action=history"/>
	<updated>2026-04-07T23:54:53Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=Synchronization_Primitives&amp;diff=377&amp;oldid=prev</id>
		<title>2022年2月5日 (六) 14:27 Zhang3</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Synchronization_Primitives&amp;diff=377&amp;oldid=prev"/>
		<updated>2022-02-05T14:27:00Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2022年2月5日 (六) 14:27的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;第1行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第1行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;这里介绍的所有技术都是解决 ''&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;进程同步&lt;/del&gt;'' &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;问题的基本构建块。 例如，给定在同一台机器上彼此独立运行的程序，如何实现一些特性确保允许哪些操作组合和不允许哪些操作组合。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;这里介绍的所有技术都是解决 ''&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;进程同步（process synchronization）&lt;/ins&gt;'' &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;问题的基本功能块。 例如，给定在同一台机器上彼此独立运行的程序，如何实现确保同时允许哪些操作组合和不允许哪些操作组合。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;在现实世界问题的其他示例中，我们正在寻找可以授予以下功能的技术&lt;/del&gt;:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;在现实世界问题的其他示例中，我们正在需要可以实现以下功能的技术&lt;/ins&gt;:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* 进程的互斥: 一部分代码不能同时由两个进程执行。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* 进程的互斥: 一部分代码不能同时由两个进程执行。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;会合&lt;/del&gt;: 在其他进程完成其操作之前，一个进程不得执行一项操作 (例如生成摘要)。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;进程会合&lt;/ins&gt;: 在其他进程完成其操作之前，一个进程不得执行一项操作 (例如生成摘要)。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* 共享读者/&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;单一作者的资源锁定方法&lt;/del&gt;: 许多进程可能同时读取一个表，但是一次只能写入一个表，且写操作同时应该阻止读者访问该表，直到表返回到一致状态为止。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* 共享读者/&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;单一写者的资源锁定方法&lt;/ins&gt;: 许多进程可能同时读取一个表，但是一次只能写入一个表，且写操作同时应该阻止读者访问该表，直到表返回到一致状态为止。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;: ''注意: 良好的同步实现不仅应保证'' '''正确'''，而且''还应保证 '' ''' 公平 ''' (所有进程都有平等的机会获得访问权限) 和 '''非饥饿''' ''(任何等待进程最终都将拥有资源)。''&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;: ''注意: 良好的同步实现不仅应保证'' '''正确'''，而且''还应保证 '' ''' 公平 ''' (所有进程都有平等的机会获得访问权限) 和 '''非饥饿''' ''(任何等待进程最终都将拥有资源)。''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 信号量 ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 信号量 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Semaphores&lt;/ins&gt;==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;信号量是确保两个或多个过程之间 [[Mutual Exclusion|互斥]] 的最古老和最广泛使用的方法之一。 信号量是 (通常) 初始化为1的特殊整数变量，只能通过一对函数进行更改。 这些函数中的每一个，在历史上被称为 “p” 和 “v” (来自荷兰语单词 “proceren”尝试和 “verhogene”增量) 都必须是 [[Atomic operation|原子操作]]。 每个信号量都有一个关联的队列，用于记录那些等待它保护资源的进程。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;信号量是确保两个或多个过程之间 [[Mutual Exclusion|互斥]] 的最古老和最广泛使用的方法之一。 信号量是 (通常) 初始化为1的特殊整数变量，只能通过一对函数进行更改。 这些函数中的每一个，在历史上被称为 “p” 和 “v” (来自荷兰语单词 “proceren”尝试和 “verhogene”增量) 都必须是 [[Atomic operation|原子操作]]。 每个信号量都有一个关联的队列，用于记录那些等待它保护资源的进程。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l49&quot;&gt;第49行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第49行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 自旋锁 Spinlocks ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 自旋锁 Spinlocks ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Spinlock | 自旋锁]] &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;尝试解决相同的 &lt;/del&gt;[[Mutual Exclusion|互斥]]&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;问题，但是如果资源繁忙，则无需依赖调度程序基础结构来使进程休眠。 &lt;/del&gt;相反，spinlock将持续检查该值，直到它发生变化，并且通常依赖于CPU上的一些原子指令 &amp;lt;tt&amp;gt;test_and_set&amp;lt;/tt&amp;gt; 来执行其任务 (请参阅 [http://developer.intel.com/design/pentium4/manuals/index_new.htm 英特尔手册]，以了解如何使用 &amp;lt;tt&amp;gt;xchg&amp;lt;/tt&amp;gt; 模拟 &amp;lt;tt&amp;gt;test_and_set&amp;lt;/tt&amp;gt; 虚拟操作码)。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Spinlock|自旋锁]]&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;同样是要处理&lt;/ins&gt;[[Mutual Exclusion|互斥]]&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;问题，但是如果资源繁忙，则自旋锁无需依赖额外的调度程序基础结构来使进程休眠。 &lt;/ins&gt;相反，spinlock将持续检查该值，直到它发生变化，并且通常依赖于CPU上的一些原子指令 &amp;lt;tt&amp;gt;test_and_set&amp;lt;/tt&amp;gt; 来执行其任务 (请参阅 [http://developer.intel.com/design/pentium4/manuals/index_new.htm 英特尔手册]，以了解如何使用 &amp;lt;tt&amp;gt;xchg&amp;lt;/tt&amp;gt; 模拟 &amp;lt;tt&amp;gt;test_and_set&amp;lt;/tt&amp;gt; 虚拟操作码)。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;虽然使用不当的自旋锁将导致单cpu系统的严重性能下降，但明智地在多cpu上使用可能会获得更高的吞吐量。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;虽然使用不当的自旋锁将导致单cpu系统的严重性能下降，但明智地在多cpu上使用可能会获得更高的吞吐量。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;如果你使用的是GCC，则它提供了一组 &lt;/del&gt;[https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/_005f_005fsync-Builtins.html 原子内置程序]，可用于实现自旋锁。 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;以下示例确保了 &lt;/del&gt;“full &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;barrier”，因此可以用作多处理器代码的简单锁。 &lt;/del&gt;''__ sync_bool_compare_and_swap ''是一个原子指令，它简单地检查给定指针后面的值是否等于第二个参数，如果是，就用第三个参数替换它并返回true-否则它什么都不做，返回false,这样以下代码中我们的锁就不断处于自旋中:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;如果你使用的是GCC，它提供了一组 &lt;/ins&gt;[https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/_005f_005fsync-Builtins.html 原子内置程序]，可用于实现自旋锁。 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;以下示例使用了 &lt;/ins&gt;“full &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;barrier”（译者注：这里指的是一种编译选项，具体请搜索 full memory barrier 完全内存屏障），因此可以用作多处理器代码的一种简单锁。 &lt;/ins&gt;''__ sync_bool_compare_and_swap ''是一个原子指令，它简单地检查给定指针后面的值是否等于第二个参数，如果是，就用第三个参数替换它并返回true-否则它什么都不做，返回false,这样以下代码中我们的锁就不断处于自旋中:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;typedef volatile int mutex_t;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;typedef volatile int mutex_t;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l71&quot;&gt;第71行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第71行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;'''* IA-32程序员注意事项 *: 如果你考虑使用spinlocks，请注意，随着spinloop完成，P4/Xeon cpu将错误地检测到可能的内存顺序违规，从而导致巨大的额外性能损失。 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;将暂停指令放入旋转锁中，以避免这种不良行为。 &lt;/del&gt;有关更多信息，请参阅 [http://developer.intel.com/design/ pentium4/manuals/index_new.htm 英特尔手册]。'''&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;'''* IA-32程序员注意事项 *: 如果你考虑使用spinlocks，请注意，随着spinloop完成，P4/Xeon cpu将错误地检测到可能的内存顺序违规，从而导致巨大的额外性能损失。 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;将暂停指令放入自旋锁中，以避免这种不良行为。 &lt;/ins&gt;有关更多信息，请参阅 [http://developer.intel.com/design/pentium4/manuals/index_new.htm 英特尔手册]。'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 另见 ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 另见 ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=Synchronization_Primitives&amp;diff=376&amp;oldid=prev</id>
		<title>Zhang3：创建页面，内容为“这里介绍的所有技术都是解决 ''进程同步'' 问题的基本构建块。 例如，给定在同一台机器上彼此独立运行的程序，如何实现一些特性确保允许哪些操作组合和不允许哪些操作组合。  在现实世界问题的其他示例中，我们正在寻找可以授予以下功能的技术: * 进程的互斥: 一部分代码不能同时由两个进程执行。 * 会合: 在其他进程完成其操作之前，一个进…”</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Synchronization_Primitives&amp;diff=376&amp;oldid=prev"/>
		<updated>2022-02-05T14:15:08Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“这里介绍的所有技术都是解决 &amp;#039;&amp;#039;进程同步&amp;#039;&amp;#039; 问题的基本构建块。 例如，给定在同一台机器上彼此独立运行的程序，如何实现一些特性确保允许哪些操作组合和不允许哪些操作组合。  在现实世界问题的其他示例中，我们正在寻找可以授予以下功能的技术: * 进程的互斥: 一部分代码不能同时由两个进程执行。 * 会合: 在其他进程完成其操作之前，一个进…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;这里介绍的所有技术都是解决 ''进程同步'' 问题的基本构建块。 例如，给定在同一台机器上彼此独立运行的程序，如何实现一些特性确保允许哪些操作组合和不允许哪些操作组合。&lt;br /&gt;
&lt;br /&gt;
在现实世界问题的其他示例中，我们正在寻找可以授予以下功能的技术:&lt;br /&gt;
* 进程的互斥: 一部分代码不能同时由两个进程执行。&lt;br /&gt;
* 会合: 在其他进程完成其操作之前，一个进程不得执行一项操作 (例如生成摘要)。&lt;br /&gt;
* 共享读者/单一作者的资源锁定方法: 许多进程可能同时读取一个表，但是一次只能写入一个表，且写操作同时应该阻止读者访问该表，直到表返回到一致状态为止。&lt;br /&gt;
&lt;br /&gt;
: ''注意: 良好的同步实现不仅应保证'' '''正确'''，而且''还应保证 '' ''' 公平 ''' (所有进程都有平等的机会获得访问权限) 和 '''非饥饿''' ''(任何等待进程最终都将拥有资源)。''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 信号量 ==&lt;br /&gt;
&lt;br /&gt;
信号量是确保两个或多个过程之间 [[Mutual Exclusion|互斥]] 的最古老和最广泛使用的方法之一。 信号量是 (通常) 初始化为1的特殊整数变量，只能通过一对函数进行更改。 这些函数中的每一个，在历史上被称为 “p” 和 “v” (来自荷兰语单词 “proceren”尝试和 “verhogene”增量) 都必须是 [[Atomic operation|原子操作]]。 每个信号量都有一个关联的队列，用于记录那些等待它保护资源的进程。&lt;br /&gt;
&lt;br /&gt;
* 函数 “p”，也称为 &amp;lt;tt&amp;gt;wait()&amp;lt;/tt&amp;gt; (或 &amp;lt;tt&amp;gt;test()&amp;lt;/tt&amp;gt;)，使信号量的值递减，如果信号量为负，将进程放在等待队列中，直到信号量被持有它的进程释放。&lt;br /&gt;
&lt;br /&gt;
* 函数 “v”，也称为 &amp;lt;tt&amp;gt;signal()&amp;lt;/tt&amp;gt; (或 &amp;lt;tt&amp;gt;release()&amp;lt;/tt&amp;gt;)，增加信号量，如果仍然为负，则指示调度程序唤醒队列中的下一个等待过程。&lt;br /&gt;
&lt;br /&gt;
请注意，一般的信号量可以做的不仅仅是保证相互排斥。 例如，可以通过使用一个信号量计数 “有多少消息可用” 和另一个计数 “有多少空闲槽可用” 来实现某些FIFO队列 (单个读取器和单个写入器)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 Message queue[N];&lt;br /&gt;
 Semaphore slots=new Semaphore(N);&lt;br /&gt;
 Semaphore messages=new Semaphore(0);&lt;br /&gt;
 int last_read=0, last_written=0;&lt;br /&gt;
 &lt;br /&gt;
 Message get() {&lt;br /&gt;
   Message m;&lt;br /&gt;
   messages.wait();&lt;br /&gt;
   m=queue[last_read]; last_read=(last_read+1)%N;&lt;br /&gt;
   slots.signal();&lt;br /&gt;
   return m;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void put(Message m) {&lt;br /&gt;
   slots.wait();&lt;br /&gt;
   queue[last_written]=m; last_written=(last_written+1)%N;&lt;br /&gt;
   messages.signal();&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 互斥 Mutexes ==&lt;br /&gt;
&lt;br /&gt;
对此的一种变体，称为 “二进制信号量”，使用布尔值而不是整数。 在这种情况下，“p” 测试信号量的值，如果为true，则将其设置为false，如果为false，则等待。 二进制 “v” 函数检查等待队列，如果它为空，则将信号量设置为true; 否则，它指示调度程序唤醒下一个排队的进程。&lt;br /&gt;
&lt;br /&gt;
无论哪种形式，重要的是，一旦进程使用完它保护的资源，就释放信号量，否则资源可能无法访问。&lt;br /&gt;
&lt;br /&gt;
请注意，虽然 “信号量” 是全球唯一的语义项，但仅说 “互斥体” 是一个模糊的名称，不同系统的设计人员倾向于拥有 “各自的互斥体”所指内容，具体比如像是自旋锁，或者二进制信号量，或者一般说信号量...&lt;br /&gt;
&lt;br /&gt;
== 自旋锁 Spinlocks ==&lt;br /&gt;
&lt;br /&gt;
[[Spinlock | 自旋锁]] 尝试解决相同的 [[Mutual Exclusion|互斥]]问题，但是如果资源繁忙，则无需依赖调度程序基础结构来使进程休眠。 相反，spinlock将持续检查该值，直到它发生变化，并且通常依赖于CPU上的一些原子指令 &amp;lt;tt&amp;gt;test_and_set&amp;lt;/tt&amp;gt; 来执行其任务 (请参阅 [http://developer.intel.com/design/pentium4/manuals/index_new.htm 英特尔手册]，以了解如何使用 &amp;lt;tt&amp;gt;xchg&amp;lt;/tt&amp;gt; 模拟 &amp;lt;tt&amp;gt;test_and_set&amp;lt;/tt&amp;gt; 虚拟操作码)。&lt;br /&gt;
&lt;br /&gt;
虽然使用不当的自旋锁将导致单cpu系统的严重性能下降，但明智地在多cpu上使用可能会获得更高的吞吐量。&lt;br /&gt;
&lt;br /&gt;
如果你使用的是GCC，则它提供了一组 [https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/_005f_005fsync-Builtins.html 原子内置程序]，可用于实现自旋锁。 以下示例确保了 “full barrier”，因此可以用作多处理器代码的简单锁。 ''__ sync_bool_compare_and_swap ''是一个原子指令，它简单地检查给定指针后面的值是否等于第二个参数，如果是，就用第三个参数替换它并返回true-否则它什么都不做，返回false,这样以下代码中我们的锁就不断处于自旋中:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef volatile int mutex_t;&lt;br /&gt;
&lt;br /&gt;
void acquire_mutex(mutex_t* mutex)&lt;br /&gt;
{&lt;br /&gt;
	while(!__sync_bool_compare_and_swap(mutex, 0, 1))&lt;br /&gt;
	{&lt;br /&gt;
		asm(&amp;quot;pause&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void release_mutex(mutex_t* mutex)&lt;br /&gt;
{&lt;br /&gt;
	*mutex = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''* IA-32程序员注意事项 *: 如果你考虑使用spinlocks，请注意，随着spinloop完成，P4/Xeon cpu将错误地检测到可能的内存顺序违规，从而导致巨大的额外性能损失。 将暂停指令放入旋转锁中，以避免这种不良行为。 有关更多信息，请参阅 [http://developer.intel.com/design/ pentium4/manuals/index_new.htm 英特尔手册]。'''&lt;br /&gt;
&lt;br /&gt;
== 另见 ==&lt;br /&gt;
=== 论坛主题 ===&lt;br /&gt;
*[[Topic:9440|Userland only Semaphores]]&lt;br /&gt;
*[[Topic:10363|Spinlocks that disable interrupts]]&lt;br /&gt;
*[[Topic:9699|SMP compatibility]]&lt;br /&gt;
*[[Topic:14261|Mutex Implementation]]&lt;br /&gt;
*[[Topic:11903|Mutexs, Spinlocks and all that jazz]]&lt;br /&gt;
*[[Topic:7500|Spinlocks &amp;amp; Semaphores]]&lt;br /&gt;
&lt;br /&gt;
=== 外部链接 ===&lt;br /&gt;
*[http://locklessinc.com/articles/locks/ Spinlocks and Read-Write locks] - 展示某些类型的自旋锁和读写锁的基本代码&lt;br /&gt;
&lt;br /&gt;
[[Category:IPC]]&lt;br /&gt;
[[Category:Synchronization]]&lt;/div&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
</feed>