亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

linux系統編程之文件與I/O(六):fcntl 函數與

系統 1861 0

一、fcntl函數

功能:操縱文件描述符,改變已打開的文件的屬性

int fcntl(int fd, int cmd, ... /* arg */ );


cmd的取值可以如下:

復制文件描述符
F_DUPFD (long)


設置/獲取文件描述符標志
F_GETFD (void)
F_SETFD (long)


設置/獲取文件狀態標志
F_GETFL (void)
F_SETFL (long)


獲取/設置文件鎖
F_GETLK
F_SETLK,F_SETLKW


其中復制文件描述符可參見《 linux系統編程之文件與I/O(五):打開文件的內核結構file和重定向 》,文件描述符的標志只有一個即FD_CLOEXEC,設置/獲取文件描述符標志等學習到進程部分再說。下面先來看設置/獲取文件狀態標志。

F_SETFL:

On Linux ?this ?command?can change only the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK flags.

示例程序如下:

?

?C++ Code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
?
/*************************************************************************
????>?File?Name:?file_fcntl.c
????>?Author:?Simba
????>?Mail:?dameng34@163.com
????>?Created?Time:?Sat?23?Feb?2013?02:34:02?PM?CST
?************************************************************************/

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#define ?ERR_EXIT(m)?\
???? do ?{?\
????????perror(m);?\
????????exit(EXIT_FAILURE);?\
????}? while ( 0 )

void ?set_flag( int ,? int );
void ?clr_flag( int ,? int );

int ?main( int ?argc,? char ?*argv[])
{
???? char ?buf[ 1024 ]?=?{ 0 };
???? int ?ret;
???? /*
????????int?flags;
????????flags?=?fcntl(0,?F_GETFL,?0);
????????if?(flags?==?-1)
????????????ERR_EXIT("fcntl?get?flag?error");
????????ret?=?fcntl(0,?SETFL,?flags?|?O_NONBLOCK);?//設置為非阻塞,但不更改其他狀態
????????if?(ret?==?-1)
????????????ERR_EXIT("fcntl?set?flag?error");
????*/

????set_flag( 0 ,?O_NONBLOCK);
????ret?=?read( 0 ,?buf,? 1024 );
???? if ?(ret?==?- 1 )
????????ERR_EXIT( "read?error" );

????printf( "buf=%s\n" ,?buf);
???? return ? 0 ;
}

void ?set_flag( int ?fd,? int ?flags)
{
???? int ?val;
????val?=?fcntl(fd,?F_GETFL,? 0 );
???? if ?(val?==?- 1 )
????????ERR_EXIT( "fcntl?get?flag?error" );
????val?|=?flags;
???? if ?(fcntl(fd,?F_SETFL,?val)?<? 0 )
????????ERR_EXIT( "fcntl?set?flag?error" );
}

void ?clr_flag( int ?fd,? int ?flags)
{
???? int ?val;
????val?=?fcntl(fd,?F_GETFL,? 0 );
???? if ?(val?==?- 1 )
????????ERR_EXIT( "fcntl?get?flag?error" );
????val?&=?~flags;
???? if ?(fcntl(fd,?F_SETFL,?val)?<? 0 )
????????ERR_EXIT( "fcntl?set?flag?error" );
}

測試輸出:

?

simba@ubuntu:~/Documents/code/linux_programming/APUE/File_IO$ ./file_fcntl?
read error: Resource temporarily unavailable

因為將標準輸入的狀態更改為非阻塞,則read不會阻塞等待輸入而立即返回錯誤,errno將被置為EAGAIN,即可以重新嘗試。


二、文件鎖結構體

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) */
? ? ?...
};

文件鎖的類型只有兩種,一種是寫鎖也叫排他鎖,一種是讀鎖也就共享鎖,可以有多個進程各持有一個讀鎖,但只能有一個進程持有寫鎖,只有對文件有對應的讀寫權限才能施加對應的鎖類型。中間三個參數 l_whence, ?l_start, l_len 決定了被鎖定的文件范圍。當fcntl 函數的cmd為F_GETLK時,flock 結構體的 l_pid 參數會返回持有某種類型鎖的進程id。進程退出或者文件描述符被關閉時,會釋放所有的鎖。


示例程序如下:

?

?C++ Code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
?
/*************************************************************************
????>?File?Name:?file_flock.c
????>?Author:?Simba
????>?Mail:?dameng34@163.com
????>?Created?Time:?Sat?23?Feb?2013?02:34:02?PM?CST
?************************************************************************/

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#define ?ERR_EXIT(m)?\
???? do ?{?\
????????perror(m);?\
????????exit(EXIT_FAILURE);?\
????}? while ( 0 )


int ?main( int ?argc,? char ?*argv[])
{
???? int ?fd;
????fd?=?open( "test2.txt" ,?O_CREAT?|?O_RDWR?|?O_TRUNC,? 0664 );
???? if ?(fd?==?- 1 )
????????ERR_EXIT( "open?error" );
???? /*?只有對文件有相應的讀寫權限才能施加對應的文件鎖?*/
???? struct ?flock?lock;
????memset(&lock,? 0 ,? sizeof (lock));
????lock.l_type?=?F_WRLCK;? //?排他鎖,即不允許其他進程再對其加任何類型的鎖,但讀鎖(共享鎖)允許
????lock.l_whence?=?SEEK_SET;
????lock.l_start?=? 0 ;? //從文件開頭開始鎖定
????lock.l_len?=? 0 ;? //?文件全部內容鎖住

???? if ?(fcntl(fd,?F_SETLK,?&lock)?==? 0 )
????{
???????? /*?若為F_SETLKW,這時如果鎖已經被其他進程占用,則此進程會阻塞直到其他進程釋放鎖*/
????????printf( "lock?success\n" );
????????printf( "press?any?key?to?unlock\n" );
????????getchar();
????????lock.l_type?=?F_UNLCK;
???????? if ?(fcntl(fd,?F_SETLK,?&lock)?==? 0 )
????????????printf( "unlock?success\n" );
???????? else
????????????ERR_EXIT( "unlock?fail" );
????}
???? else
????????ERR_EXIT( "lock?fail" );

???? return ? 0 ;? //進程退出會對所有文件解鎖
}

?

?

測試如下:

我們先在一個 終端執行程序:

simba@ubuntu:~/Documents/code/linux_programming/APUE/File_IO$ ./file_flock?
lock success
press any key to unlock


現在文件已經被鎖住了,而且沒有按下任何按鍵,所以卡在這里,也還沒解鎖,接著在另一個終端再次執行同個程序:

simba@ubuntu:~/Documents/code/linux_programming/APUE/File_IO$ ./file_flock?
lock fail: Resource temporarily unavailable

會立即返回錯誤,因為我們希望施加的是排他鎖,而現在前面一個進程正在占用寫鎖還沒釋放,所以嘗試施加鎖失敗,而如果fcntl 函數的cmd 設置為 F_SETLKW,即帶w的版本,則此進程會一直阻塞直到前面一個進程釋放了鎖。

?

linux系統編程之文件與I/O(六):fcntl 函數與文件鎖


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美日日日 | 九九精品视频在线播放 | 国产a毛片高清视 | 亚洲性另类 | 九九九九在线精品免费视频 | 日韩亚洲一区二区三区 | 91午夜精品亚洲一区二区三区 | 久9视频这里只有精品8 | 97影院97伦里片 | 欧美日本一本线在线观看 | 成人欧美一区二区三区白人 | 韩国色三级伦不卡高清在线观看 | 网色视频 | 国产精品久久成人影院 | 成人免费视频在线看 | 狠狠色噜噜狠狠狠狠色综合久 | 天天躁狠狠躁狠狠躁夜夜躁 | 免费福利视频网站 | 草的爽免费视频 | 亚洲欧美日韩一区二区在线观看 | 免费人成在线观看网站 | 久久精品在现线观看免费15 | 亚洲国产成a人v在线观看 | 久久久久国产精品免费免费不卡 | 九九精品99久久久香蕉 | 国产香蕉精品视频在 | 天天弄天天干 | 在线免费观看一级毛片 | 日日爽视频 | 精品图区 | 人人草人人干 | 久久午夜综合久久 | 国产大片在线播放 | 九九久久99综合一区二区 | 四虎影院新地址 | 99在线免费观看 | 久久香蕉国产线看免费 | 免费黄色在线 | 99秒拍福利大尺度视频 | 亚洲精品久久久久综合中文字幕 | 国产大片91精品免费观看不卡 |