详解Linux文件锁flock
<p>在多个进程同时操作同一份文件的过程中,很容易导致文件中的数据混乱,需要锁操作来保证数据的完整性,这里介绍的针对文件的锁,称之为“文件锁”-flock。</p>
<p>
flock,建议性锁,不具备强制性。一个进程使用flock将文件锁住,另一个进程可以直接操作正在被锁的文件,修改文件中的数据,原因在于flock只是用于检测文件是否被加锁,针对文件已经被加锁,另一个进程写入数据的情况,内核不会阻止这个进程的写入操作,也就是建议性锁的内核处理策略。</p>
<p>
<strong>flock主要三种操作类型:</strong></p>
<ul>
<li>
LOCK_SH,共享锁,多个进程可以使用同一把锁,常被用作读共享锁;</li>
<li>
LOCK_EX,排他锁,同时只允许一个进程使用,常被用作写锁;</li>
<li>
LOCK_UN,释放锁;</li>
</ul>
<p>
进程使用flock尝试锁文件时,如果文件已经被其他进程锁住,进程会被阻塞直到锁被释放掉,或者在调用flock的时候,采用LOCK_NB参数,在尝试锁住该文件的时候,发现已经被其他服务锁住,会返回错误,errno错误码为EWOULDBLOCK。即提供两种工作模式:阻塞与非阻塞类型。</p>
<p>
服务会阻塞等待直到锁被释放:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_678890">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp plain">flock(lockfd,LOCK_EX)</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
服务会返回错误发现文件已经被锁住时:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_252378">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp plain">ret = flock(lockfd,LOCK_EX|LOCK_NB)</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
同时ret = -1, errno = EWOULDBLOCK</p>
<p>
flock锁的释放非常具有特色,即可调用LOCK_UN参数来释放文件锁,也可以通过关闭fd的方式来释放文件锁(flock的第一个参数是fd),意味着flock会随着进程的关闭而被自动释放掉。</p>
<p>
flock其中的一个使用场景为:检测进程是否已经存在;</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_935908">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
<div class="line number15 index14 alt2">
15</div>
<div class="line number16 index15 alt1">
16</div>
<div class="line number17 index16 alt2">
17</div>
<div class="line number18 index17 alt1">
18</div>
<div class="line number19 index18 alt2">
19</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp color1 bold">int</code> <code class="cpp plain">checkexit(</code><code class="cpp color1 bold">char</code><code class="cpp plain">* pfile)</code>
</div>
<div class="line number2 index1 alt1">
<code class="cpp plain">{</code>
</div>
<div class="line number3 index2 alt2">
<code class="cpp spaces"> </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(pfile == NULL)</code>
</div>
<div class="line number4 index3 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">{ </code>
</div>
<div class="line number5 index4 alt2">
<code class="cpp spaces"> </code><code class="cpp keyword bold">return</code> <code class="cpp plain">-1; </code>
</div>
<div class="line number6 index5 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">} </code>
</div>
<div class="line number7 index6 alt2">
<code class="cpp spaces"> </code><code class="cpp color1 bold">int</code> <code class="cpp plain">lockfd = open(pfile,O_RDWR);</code>
</div>
<div class="line number8 index7 alt1">
<code class="cpp spaces"> </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(lockfd == -1) </code>
</div>
<div class="line number9 index8 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">{ </code>
</div>
<div class="line number10 index9 alt1">
<code class="cpp spaces"> </code><code class="cpp keyword bold">return</code> <code class="cpp plain">-2; </code>
</div>
<div class="line number11 index10 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">} </code>
</div>
<div class="line number12 index11 alt1">
<code class="cpp spaces"> </code><code class="cpp color1 bold">int</code> <code class="cpp plain">iret = flock(lockfd,LOCK_EX|LOCK_NB);</code>
</div>
<div class="line number13 index12 alt2">
<code class="cpp spaces"> </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(iret == -1) </code>
</div>
<div class="line number14 index13 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">{ </code>
</div>
<div class="line number15 index14 alt2">
<code class="cpp spaces"> </code><code class="cpp keyword bold">return</code> <code class="cpp plain">-3; </code>
</div>
<div class="line number16 index15 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">} </code>
</div>
<div class="line number17 index16 alt2">
</div>
<div class="line number18 index17 alt1">
<code class="cpp spaces"> </code><code class="cpp keyword bold">return</code> <code class="cpp plain">0;</code>
</div>
<div class="line number19 index18 alt2">
<code class="cpp plain">}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。</p>
<p>
原文链接:http://blog.csdn.net/jiang1013nan/article/details/17849499</p>
頁:
[1]