fcntl的使用
1、首先查看聯機幫助:
描述:fcntl系統調用可以用來對已打開的文件描述符進行各種控制操作以改變已打開文件的各種屬性。
2、下面列出常見的4種功能:
a) 複製一個現有的描述符(cmd=F_DUPFD);
調用成功,返回新的文件描述符,失敗返回-1;
b) 獲得/設置文件打開方式(cmd=F_GETFL或F_SETFL);
F_GETFL:調用成功,返回標誌值,失敗返回-1;
F_SETFL:調用成功,返回0,失敗返回-1;
c) 獲得/設置記錄鎖(cmd=F_GETLK , F_SETLK或F_SETLKW);
調用成功,返回0,失敗返回-1;
3、F_DUPFD
功能相當於dup、dup2:
(1)調用fcntl(oldfd,F_DUPFD,0)
等效於dup(oldfd);
(2)調用close(oldfd);
fcntl(oldfd,F_DUPFD,newfd)
等效於dup2(oldfd,newfd);
4、F_GETFL或F_SETFL
F_GETFL:獲得文件打開方式
例:fd=open(“hello.c”,O_CREAT|O_TRUNC|O_RDWR,S_IRWXU);
fcntl(fd,F_GETFL,0);獲取文件打開方式,即O_CREAT|O_TRUNC|O_RDWR
F_SETFL:設置文件打開方式為第三個參數arg所指定的方式。Linux只能指定三種方式:O_APPEND、O_NONBLOCK、O_ASYNC。
例:fcntl(fd,F_SETFL,O_APPEND)將文件打開方式設置位O_APPEND
5、F_GETLK , F_SETLK或F_SETLKW
此時第三個參數指向一個struct flock *lock的結構:
例:
運行結果:先創建一個名為“hello.c”的文件,然後運行程序,如下
在程序中使用fork()創建了一個子進程,然後測試兩個進程是否可以同時加讀/寫鎖。
結果顯示,在父進程中,可以先設置讀鎖,然後設置寫鎖,但是要注意,這兩個鎖並不是同時存在的,也就是說,後面設置的寫鎖會覆蓋前面設置的讀鎖;由於在子進程運行前先睡眠了一秒,所以父進程會搶先設置讀寫鎖,等待一秒過後,子進程開始設置讀寫鎖,發現設置失敗,即不同的進程間會存在鎖的不兼容(如果在一個給定字節上已經有一把或多把讀鎖,則不能在該字節上再加寫鎖;如果在一個給定字節上已經有一把獨佔性的寫鎖,則不能在對它加任何鎖)。
總結:
1. 在同一進程中,鎖也並不是同時存在的,新鎖會覆蓋舊鎖;
2. 在不同進程中,如果進程A擁有讀鎖或寫鎖,那麼進程B只能有讀鎖,不能加寫鎖;
3. 取F_SETLKW時,fcntl的功能與取F_SETLK時類似,不同的是,當希望設置的鎖因為存在其他鎖而被阻止設置時,該命令會等待相沖突的鎖被釋放;
4. 當調用 fcntl(fd, F_GETLK, lock) 時,如果鎖能被設置,該命令並不真的設置鎖,而是將l_type的值修改為F_UNLCK,然後返回。
閱讀更多 有理想的代碼dog 的文章