日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

文件I/O实践(3) --文件共享与fcntl

發布時間:2025/3/17 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 文件I/O实践(3) --文件共享与fcntl 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文件共享


一個進程打開了兩個文件

文件表條目(file-table-entry):

? ?1.文件狀態標志(file-status-flags):?讀/寫/追加/同步/非阻塞等;

? ?2.當前文件偏移量

? ?3.v節點指針


//驗證 int main(int argc, char *argv[]) {int fd1 = open("test.txt", O_RDONLY);if (fd1 == -1)err_exit("fd1 open O_RDONLY error");int fd2 = open("test.txt", O_RDWR);if (fd2 == -1)err_exit("fd2 open O_RDWR error");//讀取fd1char buf[BUFSIZ];if (read(fd1, buf, 10) == -1)err_exit("read fd1 error");cout << "fd1: " << buf << endl;//讀取fd2bzero(buf, 10);if (read(fd2, buf, 10) == -1)err_exit("read fd1 error");cout << "fd2: " << buf << endl;lseek(fd1, 0, SEEK_SET);lseek(fd2, 0, SEEK_SET);write(fd2, "Helloworld", 10);bzero(buf, 10);if (read(fd1, buf, 10) == -1)err_exit("read fd1 error");cout << "after fd2 write: " << buf << endl; }


兩個獨立的進程打開同一個文件

復制文件描述符

?

方法有三種:

1.dup

2.dup2?

#include <unistd.h> int dup(int oldfd); int dup2(int oldfd, int newfd); //示例 int main(int argc, char *argv[]) {int fd = open("text.txt", O_WRONLY|O_TRUNC);if (fd == -1)err_exit("open O_WRONLY error");// close(1); //將標準輸出關閉, 則文件描述符1將空閑 // int dupfd = dup(fd);int dupfd = dup2(fd, 1);cout << "dupfd = " << dupfd << endl; } /** 示例: 實現文件拷貝 其中execlp會在后面介紹 **/ int main(int argc, char *argv[]) {if (argc < 3)err_quit("usage: ./main file-name1 file-name2");close(STDIN_FILENO);open(argv[1], O_RDONLY);close(STDOUT_FILENO);open(argv[2], O_WRONLY|O_CREAT, 0666);execlp("/bin/cat", "cat", NULL);err_exit("execlp error"); } 3.fcntl
int fcntl(int fd, F_DUPFD, ... /* arg */ ); //示例見下

fcntl

#include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, ... /* arg */ );

? 操縱文件描述符,?改變已經打開的文件的屬性

fcntl常用操作(cmd常用取值)

F_DUPFD?(long)

復制文件描述符

?

F_GETFD?(void)

F_SETFD?(long)

文件描述符標志

?

F_GETFL?(void)

F_SETFL?(long)

文件狀態標志

?

F_GETLK

F_SETLK,F_SETLKW(阻塞)

文件鎖

//示例: 復制文件描述符 int main(int argc, char *argv[]) {int fd = open("text.txt", O_WRONLY|O_TRUNC);if (fd == -1)err_exit("open O_WRONLY error");close(1); //將標準輸出關閉, 則文件描述符1將空閑// 當cmd使用F_DUPFD時, 第三個參數代表搜索的起始位置int dupfd = fcntl(fd, F_DUPFD, 1); // 1代表: 從1開始搜索一個空閑的文件描述符if (dupfd < 0)err_exit("fcntl F_DUPFD error");cout << "dupfd = " << dupfd << endl; }

文件狀態標志

F_GETFL?(void)

?Get?the?file?access?mode?and?the?file?status?flags;?arg?is?ignored.

F_SETFL?(int)

?Set?the?file?status?flags?to??the??value??specified??by??arg.???File??access??mode(O_RDONLY,??O_WRONLY,??O_RDWR)??and??file??creation??flags?(i.e.,?O_CREAT,?O_EXCL,?O_NOCTTY,?O_TRUNC)?in?arg?are?ignored.??On?Linux?this?command?can?change?only??the?O_APPEND,?O_ASYNC,?O_DIRECT,?O_NOATIME,?and?O_NONBLOCK?flags.

//示例: 給文件描述符0設置成非阻塞模式 int main(int argc, char *argv[]) {int flags = fcntl(0, F_GETFL, 0);if (flags == -1)err_exit("fcntl get error");flags |= O_NONBLOCK;if (fcntl(0, F_SETFL, flags) == -1)err_exit("fcntl set error");char buf[BUFSIZ];if (read(0, buf, sizeof(buf)) == -1)err_exit("read STDIN_FILENO error");cout << "buffer size = " << strlen(buf) << endl;cout << buf << endl; } //示例: 文件狀態設置與清除(函數封裝) void set_fl(int fd, int setFlag) {int flags = fcntl(fd, F_GETFL, 0);if (flags == -1)err_exit("fcntl get flags error");//設置狀態flags |= setFlag;if (fcntl(fd, F_SETFL, flags) == -1)err_exit("fcntl set flags error"); } void clr_fl(int fd, int clrFlag) {int flags = fcntl(fd, F_GETFL, 0);if (flags == -1)err_exit("fcntl get flags error");//清除狀態flags &= ~clrFlag;if (fcntl(fd, F_SETFL, flags) == -1)err_exit("fcntl set flags error"); }//測試 int main(int argc, char *argv[]) {set_fl(0, O_NONBLOCK);clr_fl(0, O_NONBLOCK);char buf[BUFSIZ];if (read(0, buf, sizeof(buf)) == -1)err_exit("read STDIN_FILENO error");cout << "buffer size = " << strlen(buf) << endl;cout << buf << endl; }

文件鎖

F_SETLK?(struct?flock?*)

?Acquire??a?lock?(when?l_type?is?F_RDLCK?or?F_WRLCK)?or?release?a?lock?(when?l_type?is?F_UNLCK)?on?the?bytes?specified?by?the?l_whence,?l_start,?and?l_len??fields??of?lock.???If?a?conflicting?lock?is?held?by?another?process,?this?call?returns?-1?and?sets?errno?to?EACCES?or?EAGAIN.

F_SETLKW?(struct?flock?*) 如果加鎖不成功:會一直阻塞直到解鎖

?As?for?F_SETLK,?but?if?a?conflicting?lock?is?held?on?the?file,?then?wait?for??that?lock?to?be?released.??If?a?signal?is?caught?while?waiting,?then?the?call?is?interrupted?and?(after?the?signal??handler??has??returned)??returns??immediately??(with?return?value?-1?and?errno?set?to?EINTR;?see?signal(7)).

F_GETLK?(struct?flock?*)

?On??input??to?this?call,?lock?describes?a?lock?we?would?like?to?place?on?the?file.

?If?the?lock?could?be?placed,?fcntl()?does??not??actually??place??it,??but??returns?F_UNLCK??in??the?l_type?field?of?lock?and?leaves?the?other?fields?of?the?structure?unchanged.??If?one?or?more??incompatible??locks??would??prevent??this??lock??being?placed,??then??fcntl()??returns??details??about??one?of?these?locks?in?the?l_type,?l_whence,?l_start,?and?l_len?fields?of?lock?and?sets?l_pid?to?be?the??PID??of??the?process?holding?that?lock.

//文件鎖結構體 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) */... };

注意:?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.

//示例1 int main(int argc, char *argv[]) {int fd = open("test.txt", O_RDWR|O_CREAT|O_TRUNC, 0666);if (fd == -1)err_exit("open file error");struct flock 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) //對比下面if (fcntl(fd, F_SETLKW, &lock) == 0){cout << "file lock success, press any key to unlock..." << endl;cin.get();lock.l_type = F_UNLCK;lock.l_whence = SEEK_SET;lock.l_start = 0;lock.l_len = 0;if (fcntl(fd, F_SETLK, &lock) == -1)err_exit("file unlock error");elsecout << "file unlock success" << endl;}elseerr_exit("file lock error"); } //示例2: 打印加鎖進程號 int main(int argc, char *argv[]) {int fd = open("test.txt", O_RDWR|O_CREAT|O_TRUNC, 0666);if (fd == -1)err_exit("open file error");struct flock 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){cout << "file lock success, press any key to unlock..." << endl;cin.get();lock.l_type = F_UNLCK;lock.l_whence = SEEK_SET;lock.l_start = 0;lock.l_len = 0;if (fcntl(fd, F_SETLK, &lock) == -1)err_exit("file unlock error");elsecout << "file unlock success" << endl;}else //如果失敗, 則獲取鎖信息{if (fcntl(fd, F_GETLK, &lock) == -1)err_exit("get lock error");cout << "lock process: " << lock.l_pid << endl;if (lock.l_type == F_WRLCK)cout << "type: F_WRLCK" << endl;elsecout << "type: F_RDLCK" << endl;if (lock.l_whence == SEEK_SET)cout << "whence: SEEK_SET" << endl;else if (lock.l_whence == SEEK_END)cout << "whence: SEEK_END" << endl;elsecout << "whence: SEEK_CUR" << endl;} }

新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!

總結

以上是生活随笔為你收集整理的文件I/O实践(3) --文件共享与fcntl的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。