文件鎖進(jìn)程linux命令 linux文件加鎖命令

Linux系統(tǒng)中的守護(hù)進(jìn)程講解

守護(hù)進(jìn)程daemon,是生存期較長(zhǎng)的一種進(jìn)程。它們常常在系統(tǒng)自舉時(shí)啟動(dòng),僅在系統(tǒng)關(guān)閉時(shí)才終止。因?yàn)樗鼈儧]有控制終端,所以說它們是在后臺(tái)運(yùn)行的。UNIX系統(tǒng)有很多守護(hù)進(jìn)程,它們執(zhí)行日常事務(wù)活動(dòng)。

成都創(chuàng)新互聯(lián)長(zhǎng)期為數(shù)千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為陸良企業(yè)提供專業(yè)的成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì),陸良網(wǎng)站改版等技術(shù)服務(wù)。擁有十多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

1、系統(tǒng)自舉

自舉(bootstrapping)一詞來自于人都是靠自身的自舉機(jī)構(gòu)站立起來的這一思想。計(jì)算機(jī)必須具備自舉能力將自己所有的元件激活,以便能完成加載操作系統(tǒng)這一目的,然后再由操作系統(tǒng)承擔(dān)起那些單靠自舉代碼無法完成的更復(fù)雜的任務(wù)。

自舉只有兩個(gè)功能:加電自檢和磁盤引導(dǎo)。

加電自檢:當(dāng)我們按下計(jì)算機(jī)電源開關(guān)時(shí),頭幾秒鐘機(jī)器似乎什么反應(yīng)也沒有,其實(shí),這時(shí)的計(jì)算機(jī)正在進(jìn)行加電自檢,以斷定它的所有元件都在正確地工作。如果某個(gè)元件有故障,顯示器上就會(huì)出現(xiàn)報(bào)警提示信息(如果顯示器也不能正常工作,則以一串嘟嘟聲來報(bào)警)。由于大多數(shù)計(jì)算機(jī)工作非??煽浚与娮詸z報(bào)警非常罕見。

磁盤引導(dǎo):查找裝有操作系統(tǒng)的磁盤驅(qū)動(dòng)器。從磁盤加載操作系統(tǒng)的原因有二,一是操作系統(tǒng)升級(jí)簡(jiǎn)單容易,二是使用戶擁有選擇操作系統(tǒng)的自由。

當(dāng)加電自檢和磁盤引導(dǎo)完成時(shí),自舉操作就啟動(dòng)一個(gè)讀寫操作系統(tǒng)文件和將它們復(fù)制到隨機(jī)存儲(chǔ)器中的過程,此時(shí)的機(jī)器才是真正意義上的計(jì)算機(jī)。計(jì)算機(jī)的啟動(dòng)可以有冷啟動(dòng)和熱啟動(dòng)兩種方式 ,它們之間的差別是熱啟動(dòng)不進(jìn)行機(jī)器的自檢(機(jī)器本身配置的檢查與測(cè)試),當(dāng)計(jì)算機(jī)在使用過程中由于某些原因造成死機(jī)時(shí),可以對(duì)計(jì)算機(jī)進(jìn)行熱啟動(dòng)處理。

2、守護(hù)進(jìn)程的概念

通過ps axj命令可以查看到守護(hù)進(jìn)程:

參數(shù)a表示不僅列當(dāng)前用戶的進(jìn)程,也列出所有其他用戶的進(jìn)程,參數(shù)x表示不僅列有控制終端的進(jìn)程,也列出所有無控制終端的進(jìn)程,參數(shù)j表示列出與作業(yè)控制相關(guān)的信息。

代碼如下:PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 0 1 1 1 ? -1 Ss 0 0:01 /sbin/init 0 2 0 0 ? -1 S 0 0:00 [kthreadd] 2 3 0 0 ? -1 S 0 0:00 [migration/0] 2 4 0 0 ? -1 S 0 0:00 [ksoftirqd/0]... 1 2373 2373 2373 ? -1 Ss 0 0:00 /sbin/udevd --daemon... 1 4680 4680 4680 ? -1 Ss 0 0:00 /usr/sbin/acpid -c /etc... 1 4808 4808 4808 ? -1 Ss 102 0:00 /sbin/syslogd -u syslog...

凡是TPGID一欄寫著-1的都是沒有控制終端的進(jìn)程,也就是守護(hù)進(jìn)程。在COMMAND一列用[]括起來的名字表示內(nèi)核線程,這些線程在內(nèi)核里創(chuàng)建,沒有用戶空間代碼,因此沒有程序文件名和命令行,通常采用以k開頭的名字,表示Kernel。init進(jìn)程我們已經(jīng)很熟悉了,udevd負(fù)責(zé)維護(hù)/dev目錄下的設(shè)備文件,acpid負(fù)責(zé)電源管理,syslogd負(fù)責(zé)維護(hù)/var/log下的日志文件,可以看出,守護(hù)進(jìn)程通常采用以d結(jié)尾的`名字,表示Daemon。 創(chuàng)建守護(hù)進(jìn)程最關(guān)鍵的一步是調(diào)用setsid函數(shù)創(chuàng)建一個(gè)新的Session,并成為Session Leader。 例子: C/C++ Code復(fù)制內(nèi)容到剪貼板 void daemonize(void) { pid_t pid; printf("into deamonizen"); if (pid=fork() 0) { perror("fork"); exit(1); } else if (pid !=0) { exit(0); } setsid(); if (chdir("/") 0) { perror("chdir"); exit(1); } close(0); open("/dev/null", O_RDWR); dup2(0, 1); dup2(0, 2); printf("out deamonizen"); }

3、編寫守護(hù)進(jìn)程 在編寫守護(hù)進(jìn)程程序時(shí),需遵循一些基本規(guī)則:

(1)首先要做的是調(diào)用umask將文件模式創(chuàng)建屏蔽字設(shè)置為0。

(2)調(diào)用fork,然后使父進(jìn)程退出。

(3)調(diào)用setsid以創(chuàng)建一個(gè)新會(huì)話。

(4)將當(dāng)前工作目錄更改為根目錄。

(5)關(guān)閉不再需要的文件描述符。

(6)某些守護(hù)進(jìn)程打開/dev/null使其具有文件描述符0、1和2,任何一個(gè)試圖讀標(biāo)準(zhǔn)輸入、寫標(biāo)準(zhǔn)輸出或標(biāo)準(zhǔn)出錯(cuò)的庫例程都不會(huì)產(chǎn)生任何效果。 與守護(hù)進(jìn)程有關(guān)的一個(gè)問題是如何處理出錯(cuò)消息,需要有一個(gè)集中的守護(hù)進(jìn)程出錯(cuò)記錄設(shè)施,這就是syslogd進(jìn)程。

4、守護(hù)進(jìn)程慣例 為了正常運(yùn)作,某些守護(hù)進(jìn)程實(shí)現(xiàn)為單實(shí)例的,有就是在任一時(shí)刻只運(yùn)行該守護(hù)進(jìn)程的一個(gè)副本。文件鎖和記錄鎖機(jī)制是一種方法的基礎(chǔ),該方法用來保證一個(gè)守護(hù)進(jìn)程只有一個(gè)副本在運(yùn)行。

在UNIX系統(tǒng)中,守護(hù)進(jìn)程遵循下列公共慣例:

(1)若守護(hù)進(jìn)程使用鎖文件,那么該文件通常存放在/var/run目錄中。鎖文件的名字通常是name.pid,name是該守護(hù)進(jìn)程或服務(wù)的名字。

(2)若守護(hù)進(jìn)程支持配置選項(xiàng),那么配置文件通常存放在/etc目錄中。配置文件的名字通常是name.conf。

(3)守護(hù)進(jìn)程可用命令行啟動(dòng),但通常它們是由系統(tǒng)初始化腳本啟動(dòng)的。

(4)若一守護(hù)進(jìn)程有一配置文件,那么當(dāng)該守護(hù)進(jìn)程啟動(dòng)時(shí),它讀該文件,但在此之后一般就不會(huì)再查看它。

Linux 下三種文件鎖 —— fcntl/lockf、flock

因?yàn)槲募i的事踩了點(diǎn)坑(還是在生產(chǎn)環(huán)境),花時(shí)間了解整理了一下。以下結(jié)論基本經(jīng)過 demo 驗(yàn)證,先簡(jiǎn)略寫寫結(jié)論,總結(jié)總結(jié)歷史,有空再補(bǔ)其他的。

linux文件鎖定被使用

一、什么是文件鎖定

對(duì)于鎖這個(gè)字,大家一定不會(huì)陌生,因?yàn)槲覀兩钪芯痛嬖谥罅康逆i,它們各個(gè)方面發(fā)揮著它的作用,現(xiàn)在世界中的鎖的功能都可歸結(jié)為一句話,就是阻止某些人做某些事,例如,門鎖就是阻止除了屋主之外的人進(jìn)入這個(gè)房子,你進(jìn)入不到這個(gè)房子,也就不能使用房子里面的東西。

而因?yàn)槌绦蚪?jīng)常需要共享數(shù)據(jù),而這通常又是通過文件來實(shí)現(xiàn)的,試想一個(gè)情況,A進(jìn)程正在對(duì)一個(gè)文件進(jìn)行寫操作,而另一個(gè)程序B需要對(duì)同一個(gè)文件進(jìn)行讀操作,并以讀取到的數(shù)據(jù)作為自己程序運(yùn)行時(shí)所需要的數(shù)據(jù),這會(huì)發(fā)生什么情況呢?進(jìn)程B可能會(huì)讀到錯(cuò)亂的數(shù)據(jù),因?yàn)樗⒉恢懒硪粋€(gè)進(jìn)程A正在改寫這個(gè)文件中的數(shù)據(jù)。

為了解決類似的問題,就出現(xiàn)了文件鎖定,簡(jiǎn)單點(diǎn)來說,這是文件的一種安全的更新方式,當(dāng)一個(gè)程序正在對(duì)文件進(jìn)行寫操作時(shí),文件就會(huì)進(jìn)入一種暫時(shí)狀態(tài),在這個(gè)狀態(tài)下,如果另一個(gè)程序嘗試讀這個(gè)文件,它就會(huì)自動(dòng)停下來等待這個(gè)狀態(tài)結(jié)束。Linux系統(tǒng)提供了很多特性來實(shí)現(xiàn)文件鎖定,其中最簡(jiǎn)單的方法就是以原子操作的方式創(chuàng)建鎖文件。

用回之前的例子就是,文件鎖就是當(dāng)文件在寫的時(shí)候,阻止其他的需要寫或者要讀文件的進(jìn)程來操作這個(gè)文件。

二、創(chuàng)建鎖文件

創(chuàng)建一個(gè)鎖文件是非常簡(jiǎn)單的,我們可以使用open系統(tǒng)調(diào)用來創(chuàng)建一個(gè)鎖文件,在調(diào)用open時(shí)oflags參數(shù)要增加參數(shù)O_CREAT和O_EXCL標(biāo)志,如file_desc = open("/tmp/LCK.test", O_RDWR|O_CREAT|O_EXCL, 0444);就可以創(chuàng)建一個(gè)鎖文件/tmp/LCK.test。O_CREAT|O_EXCL,可以確保調(diào)用者可以創(chuàng)建出文件,使用這個(gè)模式可以防止兩個(gè)程序同時(shí)創(chuàng)建同一個(gè)文件,如果文件(/tmp/LCK.test)已經(jīng)存在,則open調(diào)用就會(huì)失敗,返回-1。

如果一個(gè)程序在它執(zhí)行時(shí),只需要獨(dú)占某個(gè)資源一段很短的時(shí)間,這個(gè)時(shí)間段(或代碼區(qū))通常被叫做臨界區(qū),我們需要在進(jìn)入臨界區(qū)之前使用open系統(tǒng)調(diào)用創(chuàng)建鎖文件,然后在退出臨界區(qū)時(shí)用unlink系統(tǒng)調(diào)用刪除這個(gè)鎖文件。

注意:鎖文件只是充當(dāng)一個(gè)指示器的角色,程序間需要通過相互協(xié)作來使用它們,也就是說鎖文件只是建議鎖,而不是強(qiáng)制鎖,并不會(huì)真正阻止你讀寫文件中的數(shù)據(jù)。

可以看看下面的例子:源文件文件名為filelock1.c,代碼如下:

#include unistd.h #include stdlib.h #include stdio.h #include fcntl.h #include errno.h int main() { const char *lock_file = "/tmp/LCK.test1"; int n_fd = -1; int n_tries = 10; while(n_tries--) { //創(chuàng)建鎖文件 n_fd = open(lock_file, O_RDWR|O_CREAT|O_EXCL, 0444); if(n_fd == -1) { //創(chuàng)建失敗 printf("%d - Lock already present ", getpid()); sleep(2); } else { //創(chuàng)建成功 printf("%d - I have exclusive access ", getpid()); sleep(1); close(n_fd); //刪除鎖文件,釋放鎖 unlink(lock_file); sleep(2); } } return 0; }

同時(shí)運(yùn)行同一個(gè)程序的兩個(gè)實(shí)例,運(yùn)行結(jié)果為:

?

從運(yùn)行的結(jié)果可以看出兩個(gè)程序交叉地對(duì)對(duì)文件進(jìn)行鎖定,但是真實(shí)的操作卻是,每次調(diào)用open函數(shù)去檢查/tmp/LCK.test1這個(gè)文件是否存在,如果存在open調(diào)用就失敗,顯示有進(jìn)程已經(jīng)把這個(gè)文件鎖定了,如果這個(gè)文件不存在,就創(chuàng)建這個(gè)文件,并顯示許可信息。但是這種做法有一定的缺憾,我們可以看到文件/tmp/LCK.test1被創(chuàng)建了很多次,也被unlink刪除了很多次,也就是說我們不能使用已經(jīng)事先有數(shù)據(jù)的文件作為這種鎖文件,因?yàn)槿绻募呀?jīng)存在,則open調(diào)用總是失敗。

給我的感覺是,這更像是一種對(duì)進(jìn)程工作的協(xié)調(diào)性安排,更像是二進(jìn)制信號(hào)量的作用,文件存在為0,不存在為1,而不是真正的文件鎖定。

三、區(qū)域鎖定

我們還有一個(gè)問題,就是如果同一個(gè)文件有多個(gè)進(jìn)程需要對(duì)它進(jìn)行讀寫,而一個(gè)文件同一時(shí)間只能被一個(gè)進(jìn)程進(jìn)行寫操作,但是多個(gè)進(jìn)程讀寫的區(qū)域互不相關(guān),如果總是要等一個(gè)進(jìn)程寫完其他的進(jìn)程才能對(duì)其進(jìn)行讀寫,效率又太低,那么是否可以讓多個(gè)進(jìn)程同時(shí)對(duì)文件進(jìn)行讀寫以提高數(shù)據(jù)讀寫的效率呢?

為了解決上面提到的問題,和出現(xiàn)在第二點(diǎn)中的問題,即不能把文件鎖定到指定的已存在的數(shù)據(jù)文件上的問題,我們提出了一種新的解決方案,就是區(qū)域鎖定。

簡(jiǎn)單點(diǎn)來說,區(qū)域鎖定就是,文件中的某個(gè)部分被鎖定了,但其他程序可以訪問這個(gè)文件中的其他部分。

然而,區(qū)域鎖定的創(chuàng)建和使用都比上面說的文件鎖定復(fù)雜很多。

1、創(chuàng)建區(qū)域鎖定

在Linux上為實(shí)現(xiàn)這一功能,我們可以使用fcntl系統(tǒng)調(diào)用和lockf調(diào)用,但是下面以fcntl系統(tǒng)調(diào)用來講解區(qū)域鎖定的創(chuàng)建。

fctnl的函數(shù)原理為:

int fctnl(int fildes, int command, ...);

它對(duì)一個(gè)打開的文件描述進(jìn)行操作,并能根據(jù)command參數(shù)的設(shè)置完成不同的任務(wù),它有三個(gè)可選的任務(wù):F_GETLK,F(xiàn)_SETLK,F_SETLKW,至于這三個(gè)參數(shù)的意義下面再詳述。而當(dāng)使用這些命令時(shí),fcntl的第三個(gè)參數(shù)必須是一個(gè)指向flock結(jié)構(gòu)的指針,所以在實(shí)際應(yīng)用中,fctnl的函數(shù)原型一般為:int fctnl(int fildes, int command, struct flock *flock_st);

2、flock結(jié)構(gòu)

準(zhǔn)確來說,flock結(jié)構(gòu)依賴具體的實(shí)現(xiàn),但是它至少包括下面的成員:

short l_type;文件鎖的類型,對(duì)應(yīng)于F_RDLCK(讀鎖,也叫共享鎖),F(xiàn)_UNLCK(解鎖,也叫清除鎖),F(xiàn)_WRLCK(寫鎖,也叫獨(dú)占鎖)中的一個(gè)。

short l_whence;從文件的哪個(gè)相對(duì)位置開始計(jì)算,對(duì)應(yīng)于SEEK_SET(文件頭),SEEK_CUR(當(dāng)前位置),SEEK_END(文件尾)中的一個(gè)。

off_t l_start;從l_whence開始的第l_start個(gè)字節(jié)開始計(jì)算。

off_t l_len;鎖定的區(qū)域的長(zhǎng)度。

pid_t l_pid;用來記錄參持有鎖的進(jìn)程。

成員l_whence、l_start和l_len定義了一個(gè)文件中的一個(gè)區(qū)域,即一個(gè)連續(xù)的字節(jié)集合,例如:

struct flock region;

region.l_whence = SEEK_SET;

region.l_start = 10;

region.l_len = 20;

則表示fcntl函數(shù)操作鎖定的區(qū)域?yàn)槲募^開始的第10到29個(gè)字節(jié)之間的這20個(gè)字節(jié)。

3、文件鎖的類型

從上面的flock的成員l_type的取值我們可以知道,文件鎖的類型主要有三種,這里對(duì)他們進(jìn)行詳細(xì)的解說。

F_RDLCK:

從它的名字我們就可以知道,它是一個(gè)讀鎖,也叫共享鎖。許多不同的進(jìn)程可以擁有文件同一(或重疊)區(qū)域上的讀(共享)鎖。而且只要任一進(jìn)程擁有一把讀(共享)鎖,那么就沒有進(jìn)程可以再獲得該區(qū)域上的寫(獨(dú)占)鎖。為了獲得一把共享鎖,文件必須以“讀”或“讀/寫”方式打開。

簡(jiǎn)單點(diǎn)來說就是,當(dāng)一個(gè)進(jìn)程在讀文件中的數(shù)據(jù)時(shí),文件中的數(shù)據(jù)不能被改變或改寫,這是為了防止數(shù)據(jù)被改變而使讀數(shù)據(jù)的程序讀取到錯(cuò)亂的數(shù)據(jù),而文件中的同一個(gè)區(qū)域能被多個(gè)進(jìn)程同時(shí)讀取,這是容易理解的,因?yàn)樽x不會(huì)破壞數(shù)據(jù),或者說讀操作不會(huì)改變文件的數(shù)據(jù)。

F_WRLCK:

從它的名字,我們就可以知道,它是一個(gè)寫鎖,也叫獨(dú)占鎖。只有一個(gè)進(jìn)程可以在文件中的任一特定區(qū)域擁有一把寫(獨(dú)占)鎖。一旦一個(gè)進(jìn)程擁有了這樣一把鎖,任何其他進(jìn)程都無法在該區(qū)域上獲得任何類型的鎖。為了獲得一把寫(獨(dú)占)鎖,文件也必須以“讀”或“讀/寫”方式打開。

簡(jiǎn)單點(diǎn)來說,就是一個(gè)文件同一區(qū)域(或重疊)區(qū)域進(jìn)在同一時(shí)間,只能有一個(gè)進(jìn)程能對(duì)其進(jìn)行寫操作,并且在寫操作進(jìn)行期間,其他的進(jìn)程不能對(duì)該區(qū)域進(jìn)行讀取數(shù)據(jù)。這個(gè)要求是顯然易見的,因?yàn)槿绻麅蓚€(gè)進(jìn)程同時(shí)對(duì)一個(gè)文件進(jìn)行寫操作,就會(huì)使文件的內(nèi)容錯(cuò)亂起來,而由于寫時(shí)會(huì)改變文件中的數(shù)據(jù),所以它也不允許其他進(jìn)程對(duì)文件的數(shù)據(jù)進(jìn)行讀取和刪除文件等操作。

F_UNLCK:

從它的名字就可以知道,它用于把一個(gè)鎖定的區(qū)域解鎖。

4、不同的command的意義

在前面說到fcntl函數(shù)的command參數(shù)時(shí),說了三個(gè)命令選項(xiàng),這里將對(duì)它們進(jìn)行詳細(xì)的解說。

F_GETLK命令,它用于獲取fildes(fcntl的第一個(gè)參數(shù))打開的文件的鎖信息,它不會(huì)嘗試去鎖定文件,調(diào)用進(jìn)程可以把自己想創(chuàng)建的鎖類型信息傳遞給fcntl,函數(shù)調(diào)用就會(huì)返回將會(huì)阻止獲取鎖的任何信息,即它可以測(cè)試你想創(chuàng)建的鎖是否能成功被創(chuàng)建。fcntl調(diào)用成功時(shí),返回非-1,如果鎖請(qǐng)求可以成功執(zhí)行,flock結(jié)構(gòu)將保持不變,如果鎖請(qǐng)求被阻止,fcntl會(huì)用相關(guān)的信息覆蓋flock結(jié)構(gòu)。失敗時(shí)返回-1。

所以,如果調(diào)用成功,調(diào)用程序則可以通過檢查flock結(jié)構(gòu)的內(nèi)容來判斷其是否被修改過,來檢查鎖請(qǐng)求能否被成功執(zhí)行,而又因?yàn)閘_pid的值會(huì)被設(shè)置成擁有鎖的進(jìn)程的標(biāo)識(shí)符,所以大多數(shù)情況下,可以通過檢查這個(gè)字段是否發(fā)生變化來判斷flock結(jié)構(gòu)是否被修改過。

使用F_GETLK的fcntl函數(shù)調(diào)用后會(huì)立即返回。

舉個(gè)例子來說,例如,有一個(gè)flock結(jié)構(gòu)的變量,flock_st,flock_st.l_pid = -1,文件的第10~29個(gè)字節(jié)已經(jīng)存在一個(gè)讀鎖,文件的第40~49個(gè)字節(jié)中已經(jīng)存在一個(gè)寫鎖,則調(diào)用fcntl時(shí),如果用F_GETLK命令,來測(cè)試在第10~29個(gè)字節(jié)中是否可以創(chuàng)建一個(gè)讀鎖,因?yàn)檫@個(gè)鎖可以被創(chuàng)建,所以,fcntl返回非-1,同時(shí),flock結(jié)構(gòu)的內(nèi)容也不會(huì)改變,flock_st.l_pid = -1。而如果我們測(cè)試第40~49個(gè)字節(jié)中是否可以創(chuàng)建一個(gè)寫鎖時(shí),由于這個(gè)區(qū)域已經(jīng)存在一個(gè)寫鎖,測(cè)試失敗,但是fcntl還是會(huì)返回非-1,只是flock結(jié)構(gòu)會(huì)被這個(gè)區(qū)域相關(guān)的鎖的信息覆蓋了,flock_st.l_pid為擁有這個(gè)寫鎖的進(jìn)程的進(jìn)程標(biāo)識(shí)符。

F_SETLK命令,這個(gè)命令試圖對(duì)fildes指向的文件的某個(gè)區(qū)域加鎖或解鎖,它的功能根據(jù)flock結(jié)構(gòu)的l_type的值而定。而對(duì)于這個(gè)命令來說,flock結(jié)構(gòu)的l_pid字段是沒有意義的。如果加鎖成功,返回非-1,如果失敗,則返回-1。使用F_SETLK的fcntl函數(shù)調(diào)用后會(huì)立即返回。

F_SETLKW命令,這個(gè)命令與前面的F_SETLK,命令作用相同,但不同的是,它在無法獲取鎖時(shí),即測(cè)試不能加鎖時(shí),會(huì)一直等待直到可以被加鎖為止。

5、例子

看了這么多的說明,可能你已經(jīng)很亂了,就用下面的例子來整清你的思想吧。

源文件名為filelock2.c,用于創(chuàng)建數(shù)據(jù)文件,并將文件區(qū)域加鎖,代碼如下:

#include unistd.h #include stdlib.h #include stdio.h #include fcntl.h int main() { const char *test_file = "test_lock.txt"; int file_desc = -1; int byte_count = 0; char *byte_to_write = "A"; struct flock region_1; struct flock region_2; int res = 0; //打開一個(gè)文件描述符 file_desc = open(test_file, O_RDWR|O_CREAT, 0666); if(!file_desc) { fprintf(stderr, "Unable to open %s for read/write ", test_file); exit(EXIT_FAILURE); } //給文件添加100個(gè)‘A’字符的數(shù)據(jù) for(byte_count = 0; byte_count 100; ++byte_count) { write(file_desc, byte_to_write, 1); } //在文件的第10~29字節(jié)設(shè)置讀鎖(共享鎖) region_1.l_type = F_RDLCK; region_1.l_whence = SEEK_SET; region_1.l_start = 10; region_1.l_len = 20; //在文件的40~49字節(jié)設(shè)置寫鎖(獨(dú)占鎖) region_2.l_type = F_WRLCK; region_2.l_whence = SEEK_SET; region_2.l_start = 40; region_2.l_len = 10; printf("Process %d locking file ", getpid()); //鎖定文件 res = fcntl(file_desc, F_SETLK, ?ion_1); if(res == -1) { fprintf(stderr, "Failed to lock region 1 "); } res = fcntl(file_desc, F_SETLK, ?ion_2); if(res == -1) { fprintf(stderr, "Failed to lock region 2 "); } //讓程序休眠一分鐘,用于測(cè)試 sleep(60); printf("Process %d closing file ", getpid()); close(file_desc); exit(EXIT_SUCCESS); }

下面的源文件filelock3.c用于測(cè)試上一個(gè)文件設(shè)置的鎖,測(cè)試可否對(duì)兩個(gè)區(qū)域都加上一個(gè)讀鎖,代碼如下:

#include unistd.h #include stdlib.h #include stdio.h #include fcntl.h int main() { const char *test_file = "test_lock.txt"; int file_desc = -1; int byte_count = 0; char *byte_to_write = "A"; struct flock region_1; struct flock region_2; int res = 0; //打開數(shù)據(jù)文件 file_desc = open(test_file, O_RDWR|O_CREAT, 0666); if(!file_desc) { fprintf(stderr, "Unable to open %s for read/write ", test_file); exit(EXIT_FAILURE); } //設(shè)置區(qū)域1的鎖類型 struct flock region_test1; region_test1.l_type = F_RDLCK; region_test1.l_whence = SEEK_SET; region_test1.l_start = 10; region_test1.l_len = 20; region_test1.l_pid = -1; //設(shè)置區(qū)域2的鎖類型 struct flock region_test2; region_test2.l_type = F_RDLCK; region_test2.l_whence = SEEK_SET; region_test2.l_start = 40; region_test2.l_len = 10; region_test2.l_pid = -1; //

三、解空鎖問題

如果我要給在本進(jìn)程中沒有加鎖的區(qū)域解鎖會(huì)發(fā)生什么事情呢?而如果這個(gè)區(qū)域中其他的進(jìn)程有對(duì)其進(jìn)行加鎖又會(huì)發(fā)生什么情況呢?

如果一個(gè)進(jìn)程實(shí)際并未對(duì)一個(gè)區(qū)域進(jìn)行鎖定,而調(diào)用解鎖操作也會(huì)成功,但是它并不能解其他的進(jìn)程加在同一區(qū)域上的鎖。也可以說解鎖請(qǐng)求最終的結(jié)果取決于這個(gè)進(jìn)程在文件中設(shè)置的任何鎖,沒有加鎖,但對(duì)其進(jìn)行解鎖得到的還是沒有加鎖的狀態(tài)。

當(dāng)前名稱:文件鎖進(jìn)程linux命令 linux文件加鎖命令
本文鏈接:http://muchs.cn/article32/dodhppc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、網(wǎng)站營(yíng)銷、搜索引擎優(yōu)化網(wǎng)頁設(shè)計(jì)公司、云服務(wù)器、網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司