(一)Linux系统编程之文件、目录操作

1.复制文件描述符

#include <unistd.h>

int dup(int oldfd);

oldfd-要复制的文件描述符

返回值:新的文件描述符
dup调用成功:
有两个文件描述符指向同一个文件
返回值:取最小的且没被占用的文件描述符,若错误返回-1,错误代码存入errno中。

为什么需要复制一个新的文件描述符?
一个原因是使用fdopen。fclose关闭传递给它的文件描述符fdopen,就是说如果你不希望原始文件描述符被关闭,你必须复制dup;
复制的本质是某些数据结构的共享。

dup()用来复制参数oldfd所指的文件描述词,并将它返回。此新的文件描述词和参数oldfd指的是同一个文件,共享所有的锁定、读写位置和各项权限或flags。例如,当利用lseek()对某个文件描述词作用时,另一个文件描述词的读写位置也会随着改变。不过,文件描述词之间并不共享close-on-exec旗标。

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char* argv[]){ 

}

int dup2(int oldfd,int newfd);

oldfd->hello
newfd->world

假设newfd已经指向了一个文件,首先断开close与那个文件的链接,newfd指向oldfd指向的文件

(1)文件描述符重定向
(2)oldfd和newfd指向同一个文件

newfd没有被占用,newfd指向oldfd指向的文件

dup2与dup区别时dup2可以用参数newfd指定新文件描述符的数值。若参数newfd已经被使用,则系统就会将newfd所指的文件关闭;若newfd==oldfd,则返回newfd,而不关闭newfd所指的文件。dup2所复制的文件描述符与原来的文件描述符共享各种文件状态。共享所有的锁定,读写位置和各项权限或flags等。

返回值:调用成功则返回新的文件描述符,出错则返回-1;

2.改变已经打开的文件的属性

fcntl

fcntl系统调用可以用来对已打开的文件描述符进行各种控制操作以改变已打开的各种属性

file control

  • 变参函数

  • 复制一个已有的文件描述符
    int ret=fcntl(fd,F_DUPFD);

  • 获取/设置文件状态标志
    open的状态标志
    (1)获取文件状态标识
    int flag=fcntl(fd,F_GETFL);
    (2)设置文件状态标识
    flag=flag | O_APPEND;
    fcntl(fd,F_SETFL,flag)

  • 可以更改的几个标识:O_APPEND,O_NONBLOCK

文件记录锁是fcntl函数的主要功能:
记录锁:实现只锁文件的某个部分,并且可以灵活的选择是阻塞方式还是立刻返回方式。

当fcntl用于管理文件记录锁的操作时,第三个参数指向一个struct flock *lock的结构体

struct flock{
 short_l_type;//锁的类型
 short_l_whence;//偏移量的起始位置:SEEK_SET,SEEK_CUR,SEEK_END
 off_t_l_start;//加锁的起始偏移
 off_t_l_len;//上锁字节
 pid_t_l_pid;//锁的属主进程ID
};
  • short_l_type用来指定设置共享锁(F_RDLCK,读锁)还是互斥锁(F_WDLCK,写锁).

当short_l_type的值为F_UNLCK时,传入函数中将解锁

每个进程都可以在该字节区域设置不同的读锁。
但是,给定的字节上只能设置一把写锁,并且写锁存在就不能再设置其他任何的锁,且该写锁只能被一个进程单独使用。

以上多个进程的情况。

如果是单个进程时,文件的一个区域上只能一把锁,无论是写锁还是读锁。若该区域已经存在一个锁,再在该区域上设置锁时,新锁就会覆盖旧的锁。

l_whence,l_start,l_len三个变量来确定给文件上锁的区域:
(1)l_whence确定文件内部位置的指针从哪开始,I_start确定从l_whence开始的位置的偏移量,两个变量一起确定了文件内的位置指针所先指的位置,即开始上锁的位置,然后l_len的字节数就确定了上锁的区域。

当l_len==0时,则表示锁的区域从起点开始直至最大的可能位置,就是从l_whence和l_start两个变量确定的开始位置开始上锁,将开始以后的所有区域都上锁。

为了锁整个文件,将l_whence,l_start,l_len都设置为0。

  • F_SETLK
    此时,fcntl函数用来设置或释放锁。当short_l_type为F_RDLCK为读锁,F_WDLCK为写锁,F_UNLCK为解锁。

如果锁被其他进程占用,则返回-1;

这种情况设的锁遇到锁被其他进程占用时,会立即停止进程。

  • F_SETLKW
    此时也是给文件上锁,不同于F_SETLK的是,该上锁的方式是阻塞方式。当希望设置的锁因为其他锁而被阻止设置时,该命令会等待相冲突的锁被释放。

  • F_GETLK
    第3个参数lock指向一个希望设置的锁的属性结构,如果锁能被设置,该命令并不真的设置锁,而是只修改lock的l_type为F_UNLCK,然后返回结构体。如果存在一个或多个锁与希望设置的锁相互冲突,则fcntl返回其中的一个锁的flock结构。

猜你喜欢

转载自blog.csdn.net/CarmenIsOK/article/details/89430699
今日推荐