linux系统编程笔记1

来源:互联网 发布:打谱软件overture下载 编辑:程序博客网 时间:2024/06/09 18:01

1.lseek不适用于所有类型的文件,不允许应用于管道、FIFO、socket或者终端,否则调用失败并设置errno为ESPIPE。

2.当lseek偏移量超过文件末尾,然后执行io操作,read将返回0,表示文件结尾,write却可以在文件结尾后任意位置写入数据。文件结尾和新写入数据间的空间成为文件空洞,读取文件空洞将返回以0填充的缓冲区。然而,文件空洞不占用任何磁盘空间,直到后续时刻向空洞中写入数据,文件系统才会分配磁盘块。文件空洞有占用磁盘空间少的优点,核心转储文件(core dump)是包含空洞文件的常见例子。

3.所有系统调用都是以原子操作方式执行的,内核保证系统调用的所有步骤作为独立操作一次性执行,其间不会被其他进程或线程打断。

4. open()调用时若同时指定O_EXCL和O_CREAT标志位,如果打开的文件已经存在,就能返回一个错误。

5 fcntl()用途之一是针对一个打开的文件,获取或修改其访问模式或者状态标识(open调用中可以设置的),flags=fcntl(fd,F_GETFL);得到flags后可以if(flags&O_SYNC)判断是否设置某个标识。但是对于O_RDONLY,O_WRONLY和O_RDWR标识,它们并不和文件状态标识中的某一比特位对应,需要用掩码O_ACCMODE与flag相与,将其结果与3个常量对比:

accessMode=flags&O_ACCMODE;

if(accessMode==O_WRONLY){

    ......

}

修改标志位操作如下:

flags=fcntl(fd,F_GETFL);

flags=flags|O_APPEND;

fcntl(fd,F_SETFL,flags);

6.复制文件描述符的几种方法

    newfd=dup(oldfd);

    newfd=dup2(oldfd,newfd);若newfd已打开,会先关闭newfd,期间的错误会被忽略,所以更安全的做法是先调用close(newfd);

    newfd=fcntl(oldfd,F_DUPFD,startfd);

    newfd=dup3(oldfd,newfd,O_CLOEXEC);

7. 在文件特定偏移量进行读写,而且不会改变文件原来的偏移量。

ssize_t pread(int fd,void* buf,size_t count,off_t offset);

ssize_t pwrite(int fd,const void* buf,size_t count,off_t offset);

它们相当于把以下工作变为原子操作。

offt_t orig;

orig=lseek(fd,0,SEEK_CUR);

lseek(fd,offset,SEEK_SET);

s=read(fd,buf,len);

lseek(fd,orig,SEEK_SET);

原子操作可以使得多线程同时对同一文件描述符执行io操作,不会因为其他线程修改文件偏移量而受到影响。


8. 分散输入和集中输出

ssize_t readv(int fd,const struct iovec* iov,int iovcnt);

ssize_t writev(int fd,const struct iovec* iov,int iovcnt);


struct iovec{
    void* iov_base;

   size_t iov_len;

};

原子性操作readv从fd文件中读取一片连续字节,散置与iov指定的缓冲区中,依次填满每个缓冲区。

原子性操作writev将所有数据一次性从用户内存连续的写到fd指代的文件中。

多次的read和write无法保证原子性,所以需要readv和writev。另外执行一次writev和readv比多次write和read的开销要小。


9. ssize_t preadv((int fd,const struct iovec* iov,int iovcnt,off_t offset);

ssize_t pwritev((int fd,const struct iovec* iov,int iovcnt,off_t offset);

执行的任务和readv和writev相同,但是可以指定文件偏移offset的位置。


10. 截断文件

int truncate(const char* pathname,off_t length);

int ftruncate(int fd,off_t length);

若文件当前长度大于参数length,调用将丢弃超出的部分,若小于length,调用将在文件尾部添加一系列空字节或者一个文件空洞。

注意truncate不需要open来获得文件描述符就可以修改文件内容,在系统调用中可谓独树一帜。


11.非阻塞io

打开文件时指定O_NONBLOCK标志。目的有二:

第一 open调用未能立即打开文件时,返回错误,而不是陷入阻塞,一种例外,open操作FIFO可能会陷入阻塞。

第二 调用open成功后,后续的io操作也是非阻塞的。

注意管道,fifo,套接字,设备都支持非阻塞模式。


0 0
原创粉丝点击