目次
Linuxにおけるfcntl()、lockf、flockの違い
1.flock
2.lockf と fcntl
3.两种锁的关系
ホームページ バックエンド開発 PHPチュートリアル linux_PHP チュートリアルの fcntl()、lockf、flock の違い

linux_PHP チュートリアルの fcntl()、lockf、flock の違い

Jul 12, 2016 am 08:56 AM
android

Linuxにおけるfcntl()、lockf、flockの違い

fcntl()、lockf、flockの違い
——lvyilong316

これら3つの関数の機能はファイルをロックすることです。それらの違いは?まず、flock と fcntl はシステムコールで、lockf はライブラリ関数です。 lockf は実際には fcntl のパッケージであるため、lockf と fcntl の基本的な実装は同じであり、ファイルをロックする効果も同じです。後で違いを分析する場合、fcntl と lockf は一緒にされることがほとんどです。まずは各機能の使い方を見て、それぞれの機能の使い方や効果の違いを見ていきましょう。

1.flock

l関数プロトタイプ

#include

intflock(intfd,intoperation);//fdで指定されたオープンファイルにアドバイザリーロックを適用または削除します

ここで、fdはシステムによって返されるファイルの説明ですcall open シンボル、操作オプションは次のとおりです:

LOCK_SH: 共有ロック

LOCK_EX: 排他ロックまたは排他ロック

LOCK_UN: ロック解除。

LOCK_NB: 非ブロッキング (上記の 3 つの操作で使用されます)

flock 関数について、まず最初に、flock 関数はファイル全体をロックすることしかできず、ファイルの特定の部分をロックすることはできないことを知っておく必要があります。 fcntl/lockf に基づいています。最初の重要な違いは、後者はファイルの特定の領域をロックできることです。第二に、flock は勧告ロックのみを生成できます。 Linux には必須ロック (mandatorylock) と勧告ロック (advisorylock) があることがわかっています。いわゆる強制ロックは、ドアのロックです。最も恐ろしいのは、キーが 1 つしかなく、それを操作できるプロセスが 1 つだけであることです。いわゆるアドバイザリー ロックは、本質的にはファイルにアクセスする前に、まずロックをチェックする必要がある場合に、状況に関係なく読み取りと書き込みを行う必要があります。勧告ロックは効果がありません。プロトコルに準拠し、読み取りまたは書き込みの前にロックをチェックするプロセスは、連携プロセスと呼ばれます。繰り返しますが、flock と fcntl/lockf の違いは主に fork と dup にあります。

(1) flock によって作成されたロックは、fd ではなく、ファイル オープン テーブル エントリ (structfile) に関連付けられます。これは、(fork または dup を介して) ファイル fd をコピーした後、両方の fd を介してロックを操作できる (たとえば、1 つの fd を介してロックし、別の fd を介してロックを解放する) ことができることを意味します。つまり、子プロセスは、親プロセスのロック。ただし、ロック処理中にいずれかの fd がクローズされた場合、ファイル構造が解放されないため、コピーされたすべての fd がクローズされるまでロックは解除されません。プログラムをプログラム 1 にテストします。

l プログラム 1


<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>#include <stdio.h><br /></li><li>#include <unistd.h><br /></li><li>#include <stdlib.h><br /></li><li>#include <sys/file.h><br /></li><li>int main (int argc, char ** argv)<br /></li><li>{<br /></li><li>int ret;<br /></li><li>int fd1 = open("./tmp.txt",O_RDWR);<br /></li><li>int fd2 = dup(fd1);<br /></li><li>printf("fd1: %d, fd2: %d\n", fd1, fd2);<br /></li><li>ret = flock(fd1,LOCK_EX);<br /></li><li>printf("get lock1, ret: %d\n", ret);<br /></li><li>ret = flock(fd2,LOCK_EX);<br /></li><li>printf("get lock2, ret: %d\n", ret);<br /></li><li>return 0;<br /></li><li>}</li></ol>
ログイン後にコピー

実行結果は図に示すように、fd1 のロックは fd2 によるプログラムのロックには影響しません。親子プロセスについては手順2を参照してください。

l プログラム 2

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>#include <stdio.h><br /></li><li>#include <unistd.h><br /></li><li>#include <stdlib.h><br /></li><li>#include <sys/file.h><br /></li><li>int main (int argc, char ** argv)<br /></li><li>{<br /></li><li>int ret;<br /></li><li>int pid;<br /></li><li>int fd = open("./tmp.txt",O_RDWR);<br /></li><li>if ((pid = fork()) == 0){<br /></li><li>ret = flock(fd,LOCK_EX);<br /></li><li>printf("chile get lock, fd: %d, ret: %d\n",fd, ret);<br /></li><li>sleep(10);<br /></li><li>printf("chile exit\n");<br /></li><li>exit(0);<br /></li><li>}<br /></li><li>ret = flock(fd,LOCK_EX);<br /></li><li>printf("parent get lock, fd: %d, ret: %d\n", fd, ret);<br /></li><li>printf("parent exit\n");<br /></li><li>return 0;<br /></li><li>}</li></ol>
ログイン後にコピー

実行結果は図に示すとおりです。子プロセスはロックを保持しますが、同じ fd を介してロックを取得する親プロセスには影響しません。 。

(2) 同じファイルを 2 回開くには open を使用します。取得された 2 つの fd は独立しています (最下層は 2 つのファイル オブジェクトに対応するため)。一方のファイルではロックされており、もう一方のファイル オブジェクトの前ではロックを解除できません。前のはロックが解除されていますが、ロックもできません。テストプログラムは次のとおりです。

l プログラム 3

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li style="text-align:left;">#include <stdio.h><br /></li><li style="text-align:left;">#include <unistd.h><br /></li><li style="text-align:left;">#include <stdlib.h><br /></li><li style="text-align:left;">#include <sys/file.h><br /></li><li style="text-align:left;">int main (int argc, char ** argv)<br /></li><li style="text-align:left;">{<br /></li><li style="text-align:left;">int ret;<br /></li><li style="text-align:left;">int fd1 = open("./tmp.txt",O_RDWR);<br /></li><li style="text-align:left;">int fd2 = open("./tmp.txt",O_RDWR);<br /></li><li style="text-align:left;">printf("fd1: %d, fd2: %d\n", fd1, fd2);<br /></li><li style="text-align:left;">ret = flock(fd1,LOCK_EX);<br /></li><li style="text-align:left;">printf("get lock1, ret: %d\n", ret);<br /></li><li style="text-align:left;">ret = flock(fd2,LOCK_EX);<br /></li><li style="text-align:left;">printf("get lock2, ret: %d\n", ret);<br /></li><li style="text-align:left;">return 0;<br /></li><li style="text-align:left;">}</li></ol>
ログイン後にコピー

結果は図に示すように、fd1 でロックを取得した後、fd2 でロックを取得できなくなります。

(3) exec使用後もファイルロックの状態は変わりません。

(4) NFS ファイルシステムでは flock を使用できません。NFS でファイルロックを使用したい場合は、fcntl を使用してください。

(5) flock ロックは再帰的です。つまり、dup または fork を通じて生成された 2 つの fds をデッドロックなしでロックできます。

2.lockf と fcntl

l 関数のプロトタイプ

#include

intlockf(intfd,intcmd,off_tlen);

fd は、open によって返されるオープン ファイル記述子です。

cmd の値は次のとおりです。

F_LOCK: ファイルを相互にロックします。ファイルがロックされている場合、ロックが解除されるまでブロックされます。

F_TLOCK: F_LOCK と同じですが、ファイルがロックされている場合はブロックされず、エラーが返されます。

F_ULOCK: ロックが解除されました。

F_TEST: ファイルがロックされているかどうかをテストします。ロックされていない場合は 0 を返し、そうでない場合は -1 を返します。

len: ファイルの現在位置の先頭からロックされる長さ。

関数パラメータの機能を通じて、lockf は排他ロックのみをサポートし、共有ロックをサポートしないことがわかります。

#include

#include

intfcntl(intfd,intcmd,.../*arg*/);

structflock{

...

shortl_type;/*Typeoflock:F_RDLCK,F_WRLCK,F_UNLCK*/

shortl_whence;/*Howtointerpretl_start:SEEK_SET,SEEK_CUR,SEEK_END*/

off_tl_start;/*Startingoffsetforlock*/

off_tl_len;/*Numberofbytestolock*/

pid_tl_pid;/*PIDofprocessblockingourlock(F_GETLKonly)*/

...

};

文件记录加锁相关的cmd分三种:

F_SETLK:申请锁(读锁F_RDLCK,写锁F_WRLCK)或者释放所(F_UNLCK),但是如果kernel无法将锁授予本进程(被其他进程抢了先,占了锁),不傻等,返回error。

F_SETLKW:和F_SETLK几乎一样,唯一的区别,这厮是个死心眼的主儿,申请不到,就傻等。

F_GETLK:这个接口是获取锁的相关信息:这个接口会修改我们传入的structflock。

通过函数参数功能可以看出fcntl是功能最强大的,它既支持共享锁又支持排他锁,即可以锁住整个文件,又能只锁文件的某一部分。

下面看fcntl/lockf的特性:

(1)上锁可递归,如果一个进程对一个文件区间已经有一把锁,后来进程又企图在同一区间再加一把锁,则新锁将替换老锁。

(2)加读锁(共享锁)文件必须是读打开的,加写锁(排他锁)文件必须是写打开。

(3)进程不能使用F_GETLK命令来测试它自己是否再文件的某一部分持有一把锁。F_GETLK命令定义说明,返回信息指示是否现存的锁阻止调用进程设置它自己的锁。因为,F_SETLK和F_SETLKW命令总是替换进程的现有锁,所以调用进程绝不会阻塞再自己持有的锁上,于是F_GETLK命令绝不会报告调用进程自己持有的锁。

(4)进程终止时,他所建立的所有文件锁都会被释放,队医flock也是一样的。

(5)任何时候关闭一个描述符时,则该进程通过这一描述符可以引用的文件上的任何一把锁都被释放(这些锁都是该进程设置的),这一点与flock不同。如:

fd1=open(pathname,…);

lockf(fd1,F_LOCK,0);

fd2=dup(fd1);

close(fd2);

则在close(fd2)后,再fd1上设置的锁会被释放,如果将dup换为open,以打开另一描述符上的同一文件,则效果也一样。

fd1=open(pathname,…);

lockf(fd1,F_LOCK,0);

fd2=open(pathname,…);

close(fd2);

(6)由fork产生的子进程不继承父进程所设置的锁,这点与flock也不同。

(7)在执行exec后,新程序可以继承原程序的锁,这点和flock是相同的。(如果对fd设置了close-on-exec,则exec前会关闭fd,相应文件的锁也会被释放)。

(8)支持强制性锁:对一个特定文件打开其设置组ID位(S_ISGID),并关闭其组执行位(S_IXGRP),则对该文件开启了强制性锁机制。再Linux中如果要使用强制性锁,则要在文件系统mount时,使用_omand打开该机制。

3.两种锁的关系

那么flock和lockf/fcntl所上的锁有什么关系呢?答案时互不影响。测试程序如下:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>#include <unistd.h><br /></li><li>#include <stdio.h><br /></li><li>#include <stdlib.h><br /></li><li>#include <sys/file.h><br /></li><li>int main(int argc, char **argv)<br /></li><li>{<br /></li><li>int fd, ret;<br /></li><li>int pid;<br /></li><li>fd = open("./tmp.txt", O_RDWR);<br /></li><li>ret = flock(fd, LOCK_EX);<br /></li><li>printf("flock return ret : %d\n", ret);<br /></li><li>ret = lockf(fd, F_LOCK, 0);<br /></li><li>printf("lockf return ret: %d\n", ret);<br /></li><li>sleep(100);<br /></li><li>return 0;<br /></li><li>}</li></ol>
ログイン後にコピー

测试结果如下:

$./a.out

flockreturnret:0

lockfreturnret:0

可见flock的加锁,并不影响lockf的加锁。两外我们可以通过/proc/locks查看进程获取锁的状态。

$psaux|grepa.out|grep-vgrep

123751188490.00.011904440pts/5S+01:090:00./a.out

$sudocat/proc/locks|grep18849

1:POSIXADVISORYWRITE1884908:02:8526740EOF

2:FLOCKADVISORYWRITE1884908:02:8526740EOF

我们可以看到/proc/locks下面有锁的信息:我现在分别叙述下含义:

1) POSIXFLOCK は、ロックの種類が比較的明確です。 flock システム呼び出しは FLOCK を生成し、fcntl は F_SETLK、F_SETLKW または lockf を呼び出して POSIX タイプを生成します。

2) ADVISORY は、それが勧告ロックであることを示します。 3) WRITE は、名前が示すように、書き込みロックと読み取りロックです

4) 18849 は、ロックを保持しているプロセス ID です。もちろん、このタイプのロックの場合、プロセスが終了した状況が発生します。

5) 08:02:852674 は、対応するディスク ファイルが配置されているデバイスのプライマリ デバイス、マイナー デバイス番号、およびファイルに対応する inodenumber を表します。

6) 0は実際の位置を表します。

7) EOFは終了位置を表します。これら 2 つのフィールドは fcntl タイプの場合により便利で、flock の場合は常に 0 と EOF です。

http://www.bkjia.com/PHPjc/1112546.html

本当http://www.bkjia.com/PHPjc/1112546.html技術記事 Linux の fcntl()、lockf、flock の違い - lvyilong316 これら 3 つの関数の機能はファイルをロックすることです。最初の群れ...
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

新しいレポートは、噂のSamsung Galaxy S25、Galaxy S25 Plus、Galaxy S25 Ultraのカメラアップグレードのひどい評価を提供します 新しいレポートは、噂のSamsung Galaxy S25、Galaxy S25 Plus、Galaxy S25 Ultraのカメラアップグレードのひどい評価を提供します Sep 12, 2024 pm 12:23 PM

ここ数日、Ice Universeは、サムスンの次期主力スマートフォンであると広く信じられているGalaxy S25 Ultraの詳細を着実に明らかにしている。とりわけ、リーカーはサムスンがカメラのアップグレードを1つだけ計画していると主張した

Samsung Galaxy S25 Ultraの最初のレンダリング画像がリークされ、噂のデザイン変更が明らかに Samsung Galaxy S25 Ultraの最初のレンダリング画像がリークされ、噂のデザイン変更が明らかに Sep 11, 2024 am 06:37 AM

OnLeaks は、X (旧 Twitter) のフォロワーから 4,000 ドル以上を集めようとして失敗した数日後、Android Headlines と提携して Galaxy S25 Ultra のファーストルックを提供しました。コンテキストとして、h の下に埋め込まれたレンダリング イメージ

IFA 2024 | TCLのNXTPAPER 14は、パフォーマンスではGalaxy Tab S10 Ultraに匹敵しませんが、サイズではほぼ匹敵します IFA 2024 | TCLのNXTPAPER 14は、パフォーマンスではGalaxy Tab S10 Ultraに匹敵しませんが、サイズではほぼ匹敵します Sep 07, 2024 am 06:35 AM

TCLは、2つの新しいスマートフォンの発表に加えて、NXTPAPER 14と呼ばれる新しいAndroidタブレットも発表しました。その巨大な画面サイズはセールスポイントの1つです。 NXTPAPER 14 は、TCL の代表的なブランドであるマット LCD パネルのバージョン 3.0 を搭載しています。

新しいレポートは、噂のSamsung Galaxy S25、Galaxy S25 Plus、Galaxy S25 Ultraのカメラアップグレードのひどい評価を提供します 新しいレポートは、噂のSamsung Galaxy S25、Galaxy S25 Plus、Galaxy S25 Ultraのカメラアップグレードのひどい評価を提供します Sep 12, 2024 pm 12:22 PM

ここ数日、Ice Universeは、サムスンの次期主力スマートフォンであると広く信じられているGalaxy S25 Ultraの詳細を着実に明らかにしている。とりわけ、リーカーはサムスンがカメラのアップグレードを1つだけ計画していると主張した

Vivo Y300 Pro は、7.69 mm のスリムなボディに 6,500 mAh のバッテリーを搭載 Vivo Y300 Pro は、7.69 mm のスリムなボディに 6,500 mAh のバッテリーを搭載 Sep 07, 2024 am 06:39 AM

Vivo Y300 Pro は完全に公開されたばかりで、大容量バッテリーを備えた最もスリムなミッドレンジ Android スマートフォンの 1 つです。正確に言うと、このスマートフォンの厚さはわずか 7.69 mm ですが、6,500 mAh のバッテリーを搭載しています。これは最近発売されたものと同じ容量です

Samsung Galaxy S24 FEは、4色と2つのメモリオプションで予想よりも低価格で発売されると請求されています Samsung Galaxy S24 FEは、4色と2つのメモリオプションで予想よりも低価格で発売されると請求されています Sep 12, 2024 pm 09:21 PM

サムスンは、ファンエディション(FE)スマートフォンシリーズをいつアップデートするかについて、まだ何のヒントも提供していない。現時点では、Galaxy S23 FE は 2023 年 10 月初めに発表された同社の最新版のままです。

Xiaomi Redmi Note 14 Pro Plusは、Light Hunter 800カメラを搭載した初のQualcomm Snapdragon 7s Gen 3スマートフォンとして登場します Xiaomi Redmi Note 14 Pro Plusは、Light Hunter 800カメラを搭載した初のQualcomm Snapdragon 7s Gen 3スマートフォンとして登場します Sep 27, 2024 am 06:23 AM

Redmi Note 14 Pro Plusは、昨年のRedmi Note 13 Pro Plus(Amazonで現在375ドル)の直接の後継者として正式に発表されました。予想通り、Redmi Note 14 Pro Plusは、Redmi Note 14およびRedmi Note 14 Proと並んでRedmi Note 14シリーズをリードします。李

Motorola Razr 50s は初期リークで新たな予算を折り畳める可能性があることを示す Motorola Razr 50s は初期リークで新たな予算を折り畳める可能性があることを示す Sep 07, 2024 am 09:35 AM

Motorola は今年数え切れないほどのデバイスをリリースしましたが、そのうち折りたたみ式デバイスは 2 つだけです。ちなみに、世界の大部分ではこのペアが Razr 50 および Razr 50 Ultra として受け入れられていますが、Motorola は北米では Razr 2024 および Razr 2 として提供しています。

See all articles