fcntl的作用

目录

前言

一、fcntl 的函数原型

二、常用的 fcntl 命令

1. F_DUPFD / F_DUPFD_CLOEXEC

2. F_GETFD / F_SETFD

3. F_GETFL / F_SETFL

4. F_GETLK / F_SETLK / F_SETLKW

5. F_SETOWN / F_GETOWN

三、fcntl 的常见应用场景


前言

fcntl 是 Unix 和 Linux 系统编程中的一个系统调用,用于操作文件描述符。fcntl 提供了一种通用的接口,可以用来控制文件描述符的属性和行为,支持文件加锁、文件状态标志的修改、文件描述符复制等功能。

一、fcntl 的函数原型

int fcntl(int fd, int cmd, ... /* arg */ );
  • fd:要操作的文件描述符。
  • cmd:要执行的控制命令。
  • arg:根据 cmd 的不同,可能需要传递的附加参数(可选)。

二、常用的 fcntl 命令

cmd 参数指定了要执行的操作,常用的命令包括以下几种:

1. F_DUPFD / F_DUPFD_CLOEXEC

  • 功能:复制文件描述符。

    • F_DUPFD:从给定的最小值开始寻找空闲的文件描述符,并返回新的文件描述符。
    • F_DUPFD_CLOEXEC:同样是复制文件描述符,但设置 FD_CLOEXEC 标志(该标志会使得在执行 exec 系列函数时自动关闭新描述符)。
  • 使用场景:可以用于复制文件描述符,从而使多个不同的文件描述符指向同一个文件。常用于文件共享、重定向等操作。

  • 示例

int new_fd = fcntl(fd, F_DUPFD, 0);

2. F_GETFD / F_SETFD

  • 功能:获取或设置文件描述符的标志(FD_CLOEXEC)。

    • F_GETFD:获取文件描述符标志。
    • F_SETFD:设置文件描述符标志,常用于设置 FD_CLOEXEC
  • 使用场景:在进程间继承文件描述符时,设置 FD_CLOEXEC 标志可以确保文件描述符不会在 exec 系列函数执行时被继承。

  • 示例

int flags = fcntl(fd, F_GETFD);
fcntl(fd, F_SETFD, flags | FD_CLOEXEC);  // 设置 FD_CLOEXEC 标志

3. F_GETFL / F_SETFL

  • 功能:获取或设置文件描述符的状态标志(文件状态标志)。

    • F_GETFL:获取文件状态标志。
    • F_SETFL:设置文件状态标志,例如设置成非阻塞模式、同步写等。
  • 常见的文件状态标志

    • O_NONBLOCK:设置文件描述符为非阻塞模式。
    • O_APPEND:追加模式写入。
    • O_SYNC:同步模式写入。
  • 使用场景:可以用于将文件描述符设为非阻塞模式,或者设置文件的写入同步性等。

  • 示例

int flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);  // 设置为非阻塞模式

4. F_GETLK / F_SETLK / F_SETLKW

  • 功能:获取或设置文件锁。

    • F_GETLK:查询文件锁状态。
    • F_SETLK:设置文件锁,非阻塞模式。
    • F_SETLKW:设置文件锁,阻塞模式。
  • 文件锁类型

    • F_RDLCK:共享读锁,多个进程可以同时持有。
    • F_WRLCK:独占写锁,只有一个进程可以持有写锁。
    • F_UNLCK:解锁。
  • 使用场景:进程间的文件访问控制,防止多个进程同时读写同一个文件。

  • 示例

struct flock lock;
lock.l_type = F_WRLCK;   // 申请写锁
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;          // 锁定整个文件

fcntl(fd, F_SETLK, &lock);  // 非阻塞申请写锁

5. F_SETOWN / F_GETOWN

  • 功能:设置或获取接收信号的进程或进程组 ID。

    • F_SETOWN:设置接收 SIGIO 信号的进程或进程组。
    • F_GETOWN:获取当前接收 SIGIO 信号的进程或进程组。
  • 使用场景:主要用于异步 I/O 操作,当文件描述符可读或可写时,内核会发送 SIGIO 信号给设定的进程或进程组。

  • 示例

fcntl(fd, F_SETOWN, getpid());  // 设置当前进程为 SIGIO 信号的接收者

三、fcntl 的常见应用场景

  1. 文件描述符的复制

    使用 F_DUPFD 复制文件描述符。常见于 I/O 重定向场景,如重定向标准输入、标准输出等。
  2. 文件锁机制

    使用 F_SETLKF_SETLKW 等进行文件加锁,以防止多个进程或线程同时读写同一个文件。尤其适合并发编程中的文件访问控制。
  3. 非阻塞 I/O

    使用 F_GETFLF_SETFL 结合 O_NONBLOCK 标志将文件描述符设为非阻塞模式,常用于网络编程中的非阻塞 socket 连接。
  4. 控制 FD_CLOEXEC 标志

    使用 F_GETFDF_SETFD 设置 FD_CLOEXEC,确保文件描述符在执行 exec() 系列函数时不会被继承。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值