C/C++进程文件锁 之 fcntl函数的用法总结(非阻塞O_NONBLOCK)
fcntl系統(tǒng)調(diào)用可以用來(lái)對(duì)已打開(kāi)的文件描述符進(jìn)行各種控制操作以改變已打開(kāi)文件的的各種屬性
?
函數(shù)原型:
fcntl函數(shù)功能依據(jù)cmd的值的不同而不同。參數(shù)對(duì)應(yīng)功能如下:
(1)F_DUPFD
與dup函數(shù)功能一樣,復(fù)制由fd指向的文件描述符,調(diào)用成功后返回新的文件描述符,與舊的文件描述符共同指向同一個(gè)文件。
(2)F_GETFD
讀取文件描述符close-on-exec標(biāo)志
(3)F_SETFD
將文件描述符close-on-exec標(biāo)志設(shè)置為第三個(gè)參數(shù)arg的最后一位
(4)F_GETFL
獲取文件打開(kāi)方式的標(biāo)志,標(biāo)志值含義與open調(diào)用一致
(5)F_SETF
設(shè)置文件打開(kāi)方式為arg指定方式
?
文件記錄鎖是fcntl函數(shù)的主要功能。
記錄鎖:實(shí)現(xiàn)只鎖文件的某個(gè)部分,并且可以靈活的選擇是阻塞方式還是立刻返回方式
當(dāng)fcntl用于管理文件記錄鎖的操作時(shí),第三個(gè)參數(shù)指向一個(gè)struct flock *lock的結(jié)構(gòu)體
?
short_l_type用來(lái)指定設(shè)置共享鎖(F_RDLCK,讀鎖)還是互斥鎖(F_WDLCK,寫(xiě)鎖).
當(dāng)short_l_type的值為F_UNLCK時(shí),傳入函數(shù)中將解鎖。
每個(gè)進(jìn)程可以在該字節(jié)區(qū)域上設(shè)置不同的讀鎖。
但給定的字節(jié)上只能設(shè)置一把寫(xiě)鎖,并且寫(xiě)鎖存在就不能再設(shè)其他任何鎖,且該寫(xiě)鎖只能被一個(gè)進(jìn)程單獨(dú)使用。
這是多個(gè)進(jìn)程的情況。
單個(gè)進(jìn)程時(shí),文件的一個(gè)區(qū)域上只能有一把鎖,若該區(qū)域已經(jīng)存在一個(gè)鎖,再在該區(qū)域設(shè)置鎖時(shí),新鎖會(huì)覆蓋掉舊的鎖,無(wú)論是寫(xiě)鎖還時(shí)讀鎖。
l_whence,l_start,l_len三個(gè)變量來(lái)確定給文件上鎖的區(qū)域。
l_whence確定文件內(nèi)部的位置指針從哪開(kāi)始,l_star確定從l_whence開(kāi)始的位置的偏移量,兩個(gè)變量一起確定了文件內(nèi)的位置指針先所指的位置,即開(kāi)始上鎖的位置,然后l_len的字節(jié)數(shù)就確定了上鎖的區(qū)域。
特殊的,當(dāng)l_len的值為0時(shí),則表示鎖的區(qū)域從起點(diǎn)開(kāi)始直至最大的可能位置,就是從l_whence和l_start兩個(gè)變量確定的開(kāi)始位置開(kāi)始上鎖,將開(kāi)始以后的所有區(qū)域都上鎖。
為了鎖整個(gè)文件,我們會(huì)把l_whence,l_start,l_len都設(shè)為0。
(6)F_SETLK
此時(shí)fcntl函數(shù)用來(lái)設(shè)置或釋放鎖。當(dāng)short_l_type為F_RDLCK為讀鎖,F_WDLCK為寫(xiě)鎖,F_UNLCK為解鎖。
如果鎖被其他進(jìn)程占用,則返回-1;
這種情況設(shè)的鎖遇到鎖被其他進(jìn)程占用時(shí),會(huì)立刻停止進(jìn)程。
(7)F_SETLKW
此時(shí)也是給文件上鎖,不同于F_SETLK的是,該上鎖是阻塞方式。當(dāng)希望設(shè)置的鎖因?yàn)槠渌i而被阻止設(shè)置時(shí),該命令會(huì)等待相沖突的鎖被釋放。
(8)F_GETLK
第3個(gè)參數(shù)lock指向一個(gè)希望設(shè)置的鎖的屬性結(jié)構(gòu),如果鎖能被設(shè)置,該命令并不真的設(shè)置鎖,而是只修改lock的l_type為F_UNLCK,然后返回該結(jié)構(gòu)體。如果存在一個(gè)或多個(gè)鎖與希望設(shè)置的鎖相互沖突,則fcntl返回其中的一個(gè)鎖的flock結(jié)構(gòu)。
?
非阻塞I/O使我們的操作要么成功,要么立即返回錯(cuò)誤,不被阻塞
實(shí)例
if ((rsck = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1) { #ifdef DEBUGprintf("Failed to initialize raw socket\n"); #endifexit(0); }// 設(shè)置非堵塞,作要么成功,要么立即返回錯(cuò)誤,不被阻塞 fcntl(rsck, F_SETFL, O_NONBLOCK | fcntl(rsck, F_GETFL, 0));?
總結(jié)
以上是生活随笔為你收集整理的C/C++进程文件锁 之 fcntl函数的用法总结(非阻塞O_NONBLOCK)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: AppScan---web安全检测及分析
- 下一篇: 设计模式:代理模式(C++)【代理服务器