1)文件空洞: 读空洞的内容结果为'/0'
lseek至超过文件末尾,并写数据则造成空洞。
truncate(fd)可以截短也可以生成空洞,标准未规定,系统实现不同
2) 不跟随符号连接的函数:chown,rename,remove
3) 标准I/O:
说明:是一组库函数,符合ANSI C标准
目的:合理设置缓存,提高read/write效率
如何比较fputs,fput,write,fwrite的效率?
read:取决于每次读的字符(参数n),越大越快,但需要内存越多
fgets:流缓存使得每次的用户时间基本固定,但是内核时间与read的最优n相同
对固定字节数的读写,所有方法对内核提出的读写请求相同,系统CPU时间相同
标准I/O试图读写一个块单位的数据
3)非阻塞I/O:
对于终端、网络设备、流设备:read/write调用完成的字节可能少于要求的字节,正常;而对于磁盘文件则不可以
读写管道和网络设备时,如果条件不具备,读写可能会永远阻塞(即不出错返回),称为低速调用。读写磁盘不算低速。
非阻塞处理:
设置非阻塞标志:open(NONBLOCK), fcntl(NONBLOCK)
POSIX规定,如果阻塞,read返回-1,error = EAGAIN,BSD返回EWOULDBLOCK
轮询处理能够达到功能,但是浪费了CPU时间,所以采用多路转接技术(select)
4)记录锁
POSIX支持fcntl
分为读锁和写锁:
如果不可加锁,有阻塞和不阻塞两种模式
锁与i_node和进程相关,i_node里有一个lock列表,每个lock项都有进程id
建议锁和强制锁:
建议锁由进程自己控制加解锁,如建立一个锁文件,进程协同读文件的加锁和解锁 POSIX
强制锁进程read/write时由内核检查 System V
5)多路转接
POSIX未实现。
select:BSD和SVR4都支持
select对任意的fd都支持。
select BSD不是中断后自动再启动的,而SVR4是。
select的返回值:
-1:被信号中断
0:超时,无fd准备好
>0:返回准备好的fd个数,BSD和SVR4不同
6)异步I/O
SVR4只支持流设备;BSD支持终端设备和网络
SVR4中,与流相关,信号SIGPOLL;BSD SIGIO|SIGURG
一个进程只能有一个信号
SVR4:ioctl, BSD fcntl
7)存储映射
mmap:两个异常 SIGSEGV,SIGBUS
unmap或进程终止,映射区被去除,关闭文件不会
只支持磁盘文件,不支持网络、终端等。
8) 信号
POSIX标准
sigaction不再启动
可再入的函数需要先保存error
信号处理程序中调用不可再入函数会产生不可预知的错误
POSIX:SIGCHILD和SIGCLD语义可能不同,SVR4处理SIGCLD的方式与其他信号不同
未决信号:从信号产生到传递的过程。将信号设置为阻塞即使其未决
信号不排队:
栈间跳跃:使用sigsetjmp和siglongjmp,保存信号屏蔽字
使用信号需要精细的考虑!!
volatile sig_atomic_t 保证变量不跨越页边界存取,只一条指令足够当两个不同的函数需要访问一个变量的时候,最好将变量定义为volatile
几个系统调用:
system:POSIX父进程阻塞SIGINT和SIGQUIT
sigsuspend: (atomic begin;) sigpromask;pause (atomic end;)
abort:是否清理ANSI C和POSIX不同,保证退出调用者进程
sleep:实现不同,可能与alarm干扰
常用信号:SIGCHILD/SIGCLD, SIGTERM, SIGINT, SIGSEGV,SIGBUS
9)进程间通信
管道和FIFO:POSIX
1.是否为阻塞模式
2.创建与打开同步
3.读/写同步
4.读写/关闭同步
5.多进程同步,一般两个进程
6.信号SIGPIPE,error是EPIPE
7.PIPE_BUF是管道的写缓存,进程写〉PIPE_BUF的数据会被其他进程中断
系统V的 IPC
信号量:功能强大,使用复杂 vs 记录锁
消息队列:deprecated
共享存储:同步和互斥可用文件锁或信号量来实现
如何使用IPC:
i 创建和引用IPC 关键字和标志位决定
ii 需要显示的删除IPC,无进程访问,管道即彻底删除,FIFO则只留名字在系统中
10) 精灵进程:无终端,sid = gid = pid ,修改umask = 0, close(fds)