목차
linux中fcntl()、lockf、flock的区别
1.flock
2.lockf与fcntl
3.两种锁的关系
백엔드 개발 PHP 튜토리얼 linux中fcntl()、lockf、flock的区别_PHP教程

linux中fcntl()、lockf、flock的区别_PHP教程

Jul 12, 2016 am 08:56 AM
android

linux中fcntl()、lockf、flock的区别

fcntl()、lockf、flock的区别
——lvyilong316

这三个函数的作用都是给文件加锁,那它们有什么区别呢?首先flock和fcntl是系统调用,而lockf是库函数。lockf实际上是fcntl的封装,所以lockf和fcntl的底层实现是一样的,对文件加锁的效果也是一样的。后面分析不同点时大多数情况是将fcntl和lockf放在一起的。下面首先看每个函数的使用,从使用的方式和效果来看各个函数的区别。

1.flock

l函数原型

#include

intflock(intfd,intoperation);//Applyorremoveanadvisorylockontheopenfilespecifiedbyfd,只是建议性锁

其中fd是系统调用open返回的文件描述符,operation的选项有:

LOCK_SH:共享锁

LOCK_EX:排他锁或者独占锁

LOCK_UN:解锁。

LOCK_NB:非阻塞(与以上三种操作一起使用)

关于flock函数,首先要知道flock函数只能对整个文件上锁,而不能对文件的某一部分上锁,这是于fcntl/lockf的第一个重要区别,后者可以对文件的某个区域上锁。其次,flock只能产生劝告性锁。我们知道,linux存在强制锁(mandatorylock)和劝告锁(advisorylock)。所谓强制锁,比较好理解,就是你家大门上的那把锁,最要命的是只有一把钥匙,只有一个进程可以操作。所谓劝告锁,本质是一种协议,你访问文件前,先检查锁,这时候锁才其作用,如果你不那么kind,不管三七二十一,就要读写,那么劝告锁没有任何的作用。而遵守协议,读写前先检查锁的那些进程,叫做合作进程。再次,flock和fcntl/lockf的区别主要在fork和dup。

(1)flock创建的锁是和文件打开表项(structfile)相关联的,而不是fd。这就意味着复制文件fd(通过fork或者dup)后,那么通过这两个fd都可以操作这把锁(例如通过一个fd加锁,通过另一个fd可以释放锁),也就是说子进程继承父进程的锁。但是上锁过程中关闭其中一个fd,锁并不会释放(因为file结构并没有释放),只有关闭所有复制出的fd,锁才会释放。测试程序入程序一。

l程序一


<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上锁。对于父子进程,参考程序二。

l程序二

<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)使用open两次打开同一个文件,得到的两个fd是独立的(因为底层对应两个file对象),通过其中一个加锁,通过另一个无法解锁,并且在前一个解锁前也无法上锁。测试程序如程序三:

l程序三

<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)flock不能再NFS文件系统上使用,如果要在NFS使用文件锁,请使用fcntl。

(5)flock锁可递归,即通过dup或者或者fork产生的两个fd,都可以加锁而不会产生死锁。

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。当然对于flock这种类型的锁,会出现进程已经退出的状况。

5)08:02:852674表示的对应磁盘文件的所在设备的主设备好,次设备号,还有文件对应的inodenumber。

6)0表示的是所的其实位置

7)EOF表示的是结束位置。这两个字段对fcntl类型比较有用,对flock来是总是0和EOF。

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1112546.htmlTechArticlelinux中fcntl()、lockf、flock的区别 fcntl()、lockf、flock的区别 ——lvyilong316 这三个函数的作用都是给文件加锁,那它们有什么区别呢?首先floc...
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 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 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

새로운 보고서는 소문난 삼성 갤럭시 S25, 갤럭시 S25 플러스, 갤럭시 S25 울트라 카메라 업그레이드에 대한 비판적인 평가를 제공합니다. 새로운 보고서는 소문난 삼성 갤럭시 S25, 갤럭시 S25 플러스, 갤럭시 S25 울트라 카메라 업그레이드에 대한 비판적인 평가를 제공합니다. Sep 12, 2024 pm 12:23 PM

최근 아이스 유니버스는 삼성의 차기 플래그십 스마트폰으로 널리 알려진 갤럭시 S25 울트라에 대한 세부 정보를 꾸준히 공개해 왔습니다. 무엇보다도 유출자는 삼성이 카메라 업그레이드를 하나만 가져올 계획이라고 주장했습니다.

삼성 갤럭시 S25 울트라, 디자인 변경 루머가 공개된 첫 번째 렌더링 이미지 유출 삼성 갤럭시 S25 울트라, 디자인 변경 루머가 공개된 첫 번째 렌더링 이미지 유출 Sep 11, 2024 am 06:37 AM

OnLeaks는 이제 Android Headlines와 제휴하여 X(이전 Twitter) 팔로어로부터 4,000달러 이상의 수익을 창출하려는 시도가 실패한 지 며칠 후 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은 두 가지 새로운 스마트폰을 발표하는 것과 함께 NXTPAPER 14라는 새로운 Android 태블릿도 발표했는데, TCL의 거대한 화면 크기는 판매 포인트 중 하나입니다. NXTPAPER 14는 TCL의 시그니처 브랜드인 무광택 LCD 패널 버전 3.0을 갖추고 있습니다.

Vivo Y300 Pro는 7.69mm의 슬림한 본체에 6,500mAh 배터리를 탑재했습니다. Vivo Y300 Pro는 7.69mm의 슬림한 본체에 6,500mAh 배터리를 탑재했습니다. Sep 07, 2024 am 06:39 AM

Vivo Y300 Pro는 방금 완전히 공개되었으며 대용량 배터리를 갖춘 가장 얇은 중급 Android 휴대폰 중 하나입니다. 정확히 말하면 스마트폰의 두께는 7.69mm에 불과하지만 배터리 용량은 6,500mAh입니다. 최근 출시된 것과 동일한 용량이다.

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월 초에 출시된 회사의 최신 버전으로 남아 있습니다.

Motorola Razr 50s는 초기 유출에서 가능한 새로운 예산 폴더블을 보여줍니다. Motorola Razr 50s는 초기 유출에서 가능한 새로운 예산 폴더블을 보여줍니다. Sep 07, 2024 am 09:35 AM

모토로라는 올해 셀 수 없이 많은 기기를 출시했지만 그 중 폴더블 기기는 2개뿐이었습니다. 맥락에 따라 전 세계 대부분이 Razr 50 및 Razr 50 Ultra로 쌍을 받았지만 Motorola는 북미에서 Razr 2024 및 Razr 2로 제공합니다.

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 시리즈를 주도합니다. 리

새로운 보고서는 소문난 삼성 갤럭시 S25, 갤럭시 S25 플러스, 갤럭시 S25 울트라 카메라 업그레이드에 대한 비판적인 평가를 제공합니다. 새로운 보고서는 소문난 삼성 갤럭시 S25, 갤럭시 S25 플러스, 갤럭시 S25 울트라 카메라 업그레이드에 대한 비판적인 평가를 제공합니다. Sep 12, 2024 pm 12:22 PM

최근 아이스 유니버스는 삼성의 차기 플래그십 스마트폰으로 널리 알려진 갤럭시 S25 울트라에 대한 세부 정보를 꾸준히 공개해 왔습니다. 무엇보다도 유출자는 삼성이 카메라 업그레이드를 하나만 가져올 계획이라고 주장했습니다.

See all articles