世涵爷 發表於 2024-3-28 00:00:00

详解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]
查看完整版本: 详解Linux文件锁flock