<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>梁剑的Blog &#187; 同步</title>
	<atom:link href="http://icomes.net/tag/%e5%90%8c%e6%ad%a5/feed/" rel="self" type="application/rss+xml" />
	<link>http://icomes.net</link>
	<description>做有趣的事，做有用的人</description>
	<lastBuildDate>Fri, 20 Aug 2010 16:36:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Linux下的进程同步机制 &#8211; 记录锁</title>
		<link>http://icomes.net/2009/04/18/linux%e4%b8%8b%e7%9a%84%e8%bf%9b%e7%a8%8b%e5%90%8c%e6%ad%a5%e6%9c%ba%e5%88%b6-%e8%ae%b0%e5%bd%95%e9%94%81/</link>
		<comments>http://icomes.net/2009/04/18/linux%e4%b8%8b%e7%9a%84%e8%bf%9b%e7%a8%8b%e5%90%8c%e6%ad%a5%e6%9c%ba%e5%88%b6-%e8%ae%b0%e5%bd%95%e9%94%81/#comments</comments>
		<pubDate>Sat, 18 Apr 2009 12:53:16 +0000</pubDate>
		<dc:creator>梁剑</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[技术笔记]]></category>
		<category><![CDATA[同步]]></category>
		<category><![CDATA[锁]]></category>

		<guid isPermaLink="false">http://icomes.net/?p=368</guid>
		<description><![CDATA[当可能出现几个进程争用（读、写）同一个Critical Section的时候，加锁是常用的做法。 Linux加锁的方法，除了经典的IPC（Semophore）之外，记录锁（Record Locking）提供了更简单的方法。 其实记录锁的名字叫文件锁会比较贴切一点，因为其加锁和解锁都是通过对文件的操作完成的。 文件锁的粒度大可到整个文件，小可到一个字节，长度可变，但都可以说是对应一个Record（逻辑意义上）。 对锁的控制是通过调用fcntl实现的，基本的方式如下： fcntl&#40;fd, operation, flock&#41;; fd是某个文件的句柄，该fd需要以与type相匹配的方式open operation是操作类型 F_GETLK 读取锁信息 F_SETLK 设置锁，在锁已经被占用的情况下，马上返回错误，有点类似于pthread的trylock F_SETLKW 设置锁，如果锁被其他进程占用，则阻塞 flock是个struct，用来传递锁的详细信息 short int l_type 锁的类型，可以是F_RDLCK、 F_WRLCK、F_UNLCK，分别对应读锁、写锁和解锁 short int l_whence 与l_start一起决定锁的起始位置，SEEK_SET、SEEK_CUR、SEEK_END分别对应文件的开始、当前位置和末尾，和fseek、lseek里的含义一致 off_t l_start 起始位置 off_t l_len 长度，0表示从l_start到文件的末尾。据说某些实现支持负数 pid_t l_pid 拥有锁的进程，operation为GETLK的时候会被设置 fd所对应的文件，本身不需要有数据。 由operation的取值，flock的定义可以看出，其实记录锁非常灵活。 它既可以实现排他锁（F_WRLCK），也可以实现共享锁（F_RDLCK）； 同时也支持同步锁（F_SETLKW）和异步锁（F_SETLK）。 记录锁的另一个好处时，进程退出时，会自动释放掉自己所占用的锁。 这就避免了进程异常退出时资源无法回收的问题。 速度也是需要考虑的因素，根据测试，记录锁相对最慢； 但综合考虑易用性和灵活性，我认为这样的速度损耗是可以接受的。 flock(2)是另一种实现文件锁的方法，详情可以man 2 flock。]]></description>
			<content:encoded><![CDATA[<p>当可能出现几个进程争用（读、写）同一个Critical Section的时候，加锁是常用的做法。<br />
Linux加锁的方法，除了经典的IPC（Semophore）之外，记录锁（Record Locking）提供了更简单的方法。</p>
<p>其实记录锁的名字叫文件锁会比较贴切一点，因为其加锁和解锁都是通过对文件的操作完成的。<br />
文件锁的粒度大可到整个文件，小可到一个字节，长度可变，但都可以说是对应一个Record（逻辑意义上）。</p>
<p>对锁的控制是通过调用fcntl实现的，基本的方式如下：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">fcntl<span style="color: #008000;">&#40;</span>fd, operation, flock<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<p>fd是某个文件的句柄，该fd需要以与type相匹配的方式open<br />
operation是操作类型</p>
<ul>
<li>F_GETLK  读取锁信息</li>
<li>F_SETLK   设置锁，在锁已经被占用的情况下，马上返回错误，有点类似于pthread的trylock</li>
<li>F_SETLKW 设置锁，如果锁被其他进程占用，则阻塞</li>
</ul>
<p>flock是个struct，用来传递锁的详细信息</p>
<ul>
<li>short int l_type       锁的类型，可以是F_RDLCK、 F_WRLCK、F_UNLCK，分别对应读锁、写锁和解锁</li>
<li>short int l_whence  与l_start一起决定锁的起始位置，SEEK_SET、SEEK_CUR、SEEK_END分别对应文件的开始、当前位置和末尾，和fseek、lseek里的含义一致</li>
<li>off_t l_start             起始位置</li>
<li>off_t l_len               长度，0表示从l_start到文件的末尾。据说某些实现支持负数</li>
<li>pid_t l_pid              拥有锁的进程，operation为GETLK的时候会被设置</li>
</ul>
<p>fd所对应的文件，本身不需要有数据。</p>
<p>由operation的取值，flock的定义可以看出，其实记录锁非常灵活。<br />
它既可以实现排他锁（F_WRLCK），也可以实现共享锁（F_RDLCK）；<br />
同时也支持同步锁（F_SETLKW）和异步锁（F_SETLK）。</p>
<p>记录锁的另一个好处时，进程退出时，会自动释放掉自己所占用的锁。<br />
这就避免了进程异常退出时资源无法回收的问题。</p>
<p>速度也是需要考虑的因素，根据测试，记录锁相对最慢；<br />
但综合考虑易用性和灵活性，我认为这样的速度损耗是可以接受的。</p>
<p>flock(2)是另一种实现文件锁的方法，详情可以man 2 flock。</p>
]]></content:encoded>
			<wfw:commentRss>http://icomes.net/2009/04/18/linux%e4%b8%8b%e7%9a%84%e8%bf%9b%e7%a8%8b%e5%90%8c%e6%ad%a5%e6%9c%ba%e5%88%b6-%e8%ae%b0%e5%bd%95%e9%94%81/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
