濮阳杆衣贸易有限公司

主頁(yè) > 知識(shí)庫(kù) > fcntl函數(shù)的說(shuō)明與實(shí)例 (文件加鎖)

fcntl函數(shù)的說(shuō)明與實(shí)例 (文件加鎖)

熱門(mén)標(biāo)簽:新鄭電銷(xiāo)外呼系統(tǒng)線路 樺甸電銷(xiāo)機(jī)器人 地球地圖標(biāo)注方法 怎樣給景區(qū)加百度地圖標(biāo)注 河北語(yǔ)音電銷(xiāo)機(jī)器人 電話(huà)機(jī)器人哪里有賣(mài)的 河南智能電話(huà)機(jī)器人公司 壽光百度地圖標(biāo)注中心網(wǎng)站 商戶(hù)地圖標(biāo)注

對(duì)文件加鎖是原子性的,可以用于進(jìn)程間文件操作的同步。在linux下,有三個(gè)函數(shù)可以對(duì)文件進(jìn)程加鎖,分別是fcntl、flock、lockf。這里只說(shuō)fcntl,它的用法也是最復(fù)雜的。

fcntl是file control的縮寫(xiě)。在linux下大部分設(shè)備都是文件,所以fcntl的功能也比較多,包括:

•Duplicating a file descriptor(復(fù)制文件描述符)
•File descriptor flags(操作close-on-exec標(biāo)志)
•File status flags(操作文件O_RDONLY , O_WRONLY , O_RDWR , O_APPEND , O_NONBLOCK , O_SYNC和O_ASYNC標(biāo)識(shí))
•Advisory locking(建議性鎖)
•Mandatory locking(強(qiáng)制性鎖)
•Managing signals(管理信號(hào))
•Leases(租借鎖)
•File and directory change notification (dnotify)(文件和目錄更改消息)
•Changing the capacity of a pipe(改變管道大小)

這里只說(shuō)一下Advisory locking和Mandatory locking。建議性鎖是指給文件上鎖后,只在文件上設(shè)置了一個(gè)鎖的標(biāo)識(shí)。其他進(jìn)程在對(duì)這個(gè)文件進(jìn)程操作時(shí),可以檢測(cè)到鎖的存在,但這個(gè)鎖并不能阻止它對(duì)這個(gè)文件進(jìn)行操作。這就好比紅綠燈,當(dāng)亮紅燈時(shí),告訴你不要過(guò)馬路,但如果你一定要過(guò),也攔不住你。強(qiáng)制性鎖則是當(dāng)給文件上鎖后,當(dāng)其他進(jìn)程要對(duì)這個(gè)文件進(jìn)程不兼容的操作(如上了讀鎖,另一個(gè)進(jìn)程要寫(xiě)),則系統(tǒng)內(nèi)核將阻塞后來(lái)的進(jìn)程直到第一個(gè)進(jìn)程將鎖解開(kāi)。在該功能下,fcntl的函數(shù)原型為:


復(fù)制代碼
代碼如下:

#include unistd.h>
#include fcntl.h>/p> p>int fcntl(int fd, int cmd,struct flock *plock );/p> p>struct flock {
...
short l_type; /* Type of lock: F_RDLCK,
F_WRLCK, F_UNLCK */
short l_whence; /* How to interpret l_start:
SEEK_SET, SEEK_CUR, SEEK_END */
off_t l_start; /* Starting offset for lock */
off_t l_len; /* Number of bytes to lock */
pid_t l_pid; /* PID of process blocking our lock
(F_GETLK only) */
...
};

Advisory locking共有三個(gè)操作,分別是F_GETLK、F_SETLK、F_SETLKW。其中F_GETLK用來(lái)測(cè)試鎖,注意是測(cè)試而不是獲取鎖;F_SETLK用來(lái)加鎖、解鎖;F_SETLKW功能同F(xiàn)_SETLK,只是操作變成阻塞式的。而fcntl可以用過(guò)l_whence、l_start、l_len來(lái)控制文件上鎖的區(qū)間。下面分別是上鎖、測(cè)試鎖的代碼。


復(fù)制代碼
代碼如下:

/* slock.c *//p> p>#include unistd.h>
#include fcntl.h>
#include sys/types.h>
#include sys/stat.h>/p> p>int main()
{
struct flock _lock;/p> p> _lock.l_type = F_WRLCK;
_lock.l_whence = SEEK_SET;
_lock.l_start = 0;
_lock.l_len = 0;/p> p> int fd = open( "/dev/shm/test",O_CREAT|O_RDWR,S_IRWXU|S_IRGRP|S_IWGRP|S_IRWXO );
if ( fd 0 )
{
puts( "open error" );
return 0;
}/p> p> int ret = fcntl( fd,F_SETLK,_lock );
if ( ret 0 )
{
puts( "fcntl error" );
close( fd );
return 0;
}/p> p> puts( "sleep now ..." );
sleep( 100 );
puts( "exit..." );

_lock.l_type = F_UNLCK;
_lock.l_whence = SEEK_SET;
_lock.l_start = 0;
_lock.l_len = 0;/p> p> ret = fcntl( fd,F_SETLK,_lock );
if ( ret 0 )
{
puts( "unlock error" );
}/p> p> close( fd );
}


復(fù)制代碼
代碼如下:

/* glock.c *//p> p>#include unistd.h>
#include fcntl.h>
#include sys/types.h>
#include sys/stat.h>
#include stdio.h>/p> p>int main()
{
struct flock _lock;/p> p> _lock.l_type = F_RDLCK;
_lock.l_whence = SEEK_SET;
_lock.l_start = 0;
_lock.l_len = 0;/p> p> int fd = open( "/dev/shm/test",O_RDWR );
if ( fd 0 )
{
perror( "open error" );
return 0;
}/p> p> int ret = fcntl( fd,F_GETLK,_lock );
if ( ret 0 )
{
perror( "fcntl error:" );
close( fd );
return 0;
}/p> p> printf( "lock is %d\n",_lock.l_type );/p> p> close( fd );
}

在上面的代碼中,"_lock.l_type =  F_RDLCK;"表示給文件上讀共享鎖,"_lock.l_whence = SEEK_SET;"表示從文件開(kāi)頭開(kāi)始加鎖,"_lock.l_start = 0;"表示偏移l_whence多少字節(jié)開(kāi)始加鎖,"_lock.l_len = 0;"表示加鎖的字節(jié)數(shù),即長(zhǎng)度(Specifying 0  for  l_len  has  the  special meaning:  lock all bytes starting at the location specified by l_whence and l_start through to the end of file, no matter how  large  the  file grows.)。

在上面的代碼中,分別編譯為slock、glock。先運(yùn)行slock再運(yùn)行g(shù)lock:


復(fù)制代碼
代碼如下:

./slock
sleep now ...
./glock
lock is 1
exit...

slock先給文件上寫(xiě)鎖,然后glock測(cè)試讀共享鎖是否能加上,測(cè)試結(jié)果是已存在一個(gè)寫(xiě)鎖(F_WRLCK,debian下定義為1)。這里需要注意的是F_GETLK是測(cè)試鎖是否能加上,如果可以,則struct flock中的l_type為F_UNLCK;如果不行,則l_type為文件當(dāng)前鎖的類(lèi)型,而l_pid為上鎖的進(jìn)程pid。故如果slock上的鎖是F_RDLCK,glock測(cè)試的鎖也是F_RDLCK,這兩個(gè)鎖是兼容的,返回的l_type類(lèi)型為F_UNLCK。即你不能通過(guò)F_GETLK來(lái)判斷文件是否上鎖,只能測(cè)試某個(gè)鎖是否能加上。

  上面的是建議性鎖,如果要實(shí)現(xiàn)強(qiáng)制性鎖,則:


復(fù)制代碼
代碼如下:

To make use of mandatory locks, mandatory locking must be enabled both on the filesystem that contains the file to be locked, and on the file itself. Mandatory locking is enabled on a filesystem using the "-o
    mand" option to mount(8), or the MS_MANDLOCK flag for mount(2). Mandatory locking is enabled on a file by disabling group execute permission
on the file and enabling the set-group-ID permission bit (see chmod(1) and chmod(2)).

這是說(shuō),要實(shí)現(xiàn)強(qiáng)制性鎖則須將文件所在的文件系統(tǒng)用"-o mand"參數(shù)來(lái)掛載,并且使用chmod函數(shù)將文件用戶(hù)組的x權(quán)限去掉。然后用上面同樣的代碼就可以了。我第一次見(jiàn)這么奇特的函數(shù),實(shí)現(xiàn)一個(gè)功能并不是通過(guò)本身的參數(shù)控制,而是系統(tǒng)設(shè)置.....幸好我也不用強(qiáng)制性鎖。

  以上是fcntl加文件鎖的簡(jiǎn)單例子。需要注意的是不同系統(tǒng)的實(shí)現(xiàn)并不一樣,宏定義也不一樣。如:

http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/sys/fcntl.h

 /* record locking flags (F_GETLK, F_SETLK, F_SETLKW) */
#define    F_RDLCK        1        /* shared or read lock */
#define    F_UNLCK        2        /* unlock */
#define    F_WRLCK        3        /* exclusive or write lock */

 

而在debian中,/usr/include/bits/fcntl.h
/* For posix fcntl() and `l_type' field of a `struct flock' for lockf().  */
#define F_RDLCK         0       /* Read lock.  */
#define F_WRLCK         1       /* Write lock.  */
#define F_UNLCK         2       /* Remove lock.  */

標(biāo)簽:來(lái)賓 阜陽(yáng) 迪慶 淄博 楚雄 遼陽(yáng) 荊州 忻州

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《fcntl函數(shù)的說(shuō)明與實(shí)例 (文件加鎖)》,本文關(guān)鍵詞  fcntl,函數(shù),的,說(shuō)明,與,實(shí)例,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《fcntl函數(shù)的說(shuō)明與實(shí)例 (文件加鎖)》相關(guān)的同類(lèi)信息!
  • 本頁(yè)收集關(guān)于fcntl函數(shù)的說(shuō)明與實(shí)例 (文件加鎖)的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    八宿县| 泽州县| 若羌县| 夹江县| 黑水县| 平武县| 鄢陵县| 钟祥市| 阜新市| 囊谦县| 南部县| 丹江口市| 木兰县| 长顺县| 晋江市| 辛集市| 双流县| 苍山县| 北海市| 达孜县| 台南县| 奎屯市| 浪卡子县| 青海省| 绥江县| 稻城县| 社旗县| 潼南县| 肇庆市| 陆河县| 桃江县| 辽阳市| 综艺| 凤冈县| 安阳市| 九台市| 顺义区| 鹤峰县| 桂东县| 绵竹市| 理塘县|