文件共享与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.fcntlint fcntl(int fd, F_DUPFD, … /* arg */ );//示例见下#include <unistd.h>#include <fcntl.h>int fcntl(int fd, int cmd, … /* arg */ );

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)

Getthefileaccessmodeandthefilestatusflags;argisignored.

F_SETFL(int)

Setthefilestatusflagstothevaluespecifiedbyarg.Fileaccessmode(O_RDONLY,O_WRONLY,O_RDWR)andfilecreationflags(i.e.,O_CREAT,O_EXCL,O_NOCTTY,O_TRUNC)inargareignored.OnLinuxthiscommandcanchangeonlytheO_APPEND,O_ASYNC,O_DIRECT,O_NOATIME,andO_NONBLOCKflags.

//示例: 给文件描述符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(structflock*)

每个人在他的人生发轫之初,总有一段时光,

文件共享与fcntl

相关文章:

你感兴趣的文章:

标签云: