《UNIX 环境高级编程》学习笔记——高级I/O

非阻塞I/O

非阻塞I/O使我们可以发出 open、read 和 write 这样的I/O操作,并使这些操作不会永远阻塞。如果这种操作不能完成,则调用立即出错返回,表示该操作如继续执行将阻塞。

对于一个给定的描述符,有两种为其指定非阻塞I/O的方法。

  • (1)如果调用 open 获得描述符,则可指定 O_NONBLOCK 标志。
  • (2)对已经打开描述符,调用 fcntl 打开O_NONBLOCK文件标志。

非阻塞在I/O,会立即返回;通过返回结果可获知是否正确完成信息。

记录锁

记录锁的功能是:当第一个进程正在读或修改文件的某个部分时,使用记录锁可以阻止其他进程修改同一文件区。

fcntl记录锁

#include <fcntl.h>
int fcntl(
	int fd, 
	// F_GETLK/F_SETLK/F_SETLKW
	// cmd为F_GETLK,参数3-flock*是一个值-结果参数
	int cmd, 
	...);
	                            返回值:若成功,依赖于 cmd ,否则,返回-1
struct flock
{
   
	// F_RDLCK/F_WRLCK/F_UNLCK
	short l_type;
	// SEEK_SET/SEEK_CUR/SEEK_END
	short l_whence;
	// start offset
	off_t l_start;
	off_t l_len;
	// 返回持有此锁的进程的ID
	pid_t l_pid;
};

调用进程已经持有文件A区间A的一个锁后,希望再对文件A区间A加另一个锁,处理方式是直接用新锁替换旧锁(进程对文件A区间A只加一个锁,锁为最后调用fcntl施加的那个)。

锁的隐含继承和释放

关于记录锁的自动继承和释放有3条规则。

  • (1)锁与进程和文件两者相关联。
    这有两重含义:第一重很明显,当一个进程终止时,它所建立的锁全部释放;第二重则不太明显,无论一个描述符何时关闭,该进程通过这一描述符引用的文件上的任何一把锁都会释放(这些锁都是该进程设置的)。
  • (2)由fork产生的子进程不继承父进程所设置的锁。
    意味着,若一个进程得到一把锁,然后调用 fork ,那么对于父进程获得的锁而言,子进程被视为另一个进程。
    对于通过 fork 从父进程处继承过来的描述符,子进程需要调用 fcntl 才能获得它自己的锁。
  • (3)在执行 exec 后,新程序可以继承原执行程序的锁。
    注意,如果对于各文件描述符设置了执行时关闭标志,那么当作为 exec 的一部分关闭该文件描述符时,将释放相应文件的所有锁。

FreeBSD

记录锁通过文件+进程来标识。

在这里插入图片描述

在父进程中,关闭 fd1,fd2 或 fd3

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值