1. partial block operations are inefficient.

The operating system has to “fix up” your I/O by ensuring that everything occurs on block-aligned boundaries and rounding up to the next largest block

 
用户级程序可能在某一时刻仅仅读写一个字节,这是极大的浪费。Each of those one-byte writes is actually writing a whole block
user-buffered I/O:a way for applications to read and write data in whatever amounts feel natural but have the actual I/O occur in units of the filesystem
block size

2. User-buffered I/O

上如表明,只要将执行I/O操作的请求数设置为物理I/O块大小的整数倍 就可以获得很大的性能提升。Larger multiples will simply result in fewer system calls
使用stat系统调用可以获知文件I/O块大小
 
 #include <stdio.h>

 int main(int argc, char* argv[])
{
struct private {
char name[]; /* real name */
unsigned long booty; /* in pounds sterling */
unsigned int beard_len; /* in inches */
};
struct private p;
struct private blackbeard = {"Edward Teach", , }; FILE* out = fopen("data", "r");
if (out == NULL) {
fpiintf(stderr, "fopen error\n");
return ;
} if (fwrite(&blackbeard, sizeof(struct private), , out) == ) {
fprintf(stderr, "fwrite error\n");
return ;
} if (fclose(out)) {
fprintf(stderr, "fclose error\n");
return ;
} FILE* in = fopen("data", "r");
if (in == NULL) {
fprintf(stderr, "fopen error\n");
return ;
}
if (fread(&p, sizeof(struct private), , in) == ) {
fprintf(stderr, "fread error\n");
return ;
} if (fclose(in)) {
fprintf(stderr, "fclose error\n");
return ;
} fprintf(stdout, "name = \"%s\" booty = %lu beard_len = %u\n", p.name, p.booty, p.beard_len);
return ;
}
it's important to bear in mind that because of differences in variable sizes, alignment, and so on, binary data written with one application may not be readable by other applications. These things are guaranteed to remain constant only on a particular machine type with a particular ABI
 
fflush() merely writes the user-buffered data out to the kernel buffer. Calling fflush(), followed immediately by fsync(): that is, first ensure that
the  user buffer is written out to the kernel and then ensure that the kernel's buffer is written  out to disk.
int fileno (FILE *stream);   //返回文件流(C标准I/O库)对应的文件描述符(Unix系统调用) 
绝不能混用Unix系统调用I/O和C语言标准I/O
You should almost never  intermix file descriptor and stream-based I/O operations
 

3. 控制缓冲

标准I/O提供三种类型缓冲:
(1) 无缓冲:Data is submitted directly to the kernel. 无性能优势,基本不用。标准错误默认是无缓冲
(2) 行缓冲: With each newline character, the buffer is submitted to the kernel.  终端文件(标准输入输出)默认是行缓冲
(3) 块缓冲:Buffering is performed on a per-block basis. By default, all streams associated with files are block-buffered
 

4. 线程安全

标准I/O函数本身是线程安全的。标准I/O函数使用锁机制来确保进程内的多个线程可以并发执行标准I/O操作。(注意:确保线程安全的原子区域仅限于单一函数,多个I/O函数之间并不保证)
Any given thread must acquire the lock and become the owning thread before issuing any I/O requests,within the context of single function calls,
standard I/O operations are atomic
 
void flockfile (FILE *stream);
void funlockfile (FILE *stream);
 

5.标准I/O的缺陷

The biggest complaint with standard I/O is the performance impact from the double copy
reading data: kernel ==> standard I/O buffer ==> application buffer
writing data: application data ==> standard I/O buffer ==> kernel

Linux System Programming 学习笔记(三) 标准缓冲I/O的更多相关文章

  1. Linux System Programming 学习笔记(十一) 时间

    1. 内核提供三种不同的方式来记录时间 Wall time (or real time):actual time and date in the real world Process time:the ...

  2. Linux System Programming 学习笔记(四) 高级I/O

    1. Scatter/Gather I/O a single system call  to  read or write data between single data stream and mu ...

  3. Linux System Programming 学习笔记(二) 文件I/O

    1.每个Linux进程都有一个最大打开文件数,默认情况下,最大值是1024 文件描述符不仅可以引用普通文件,也可以引用套接字socket,目录,管道(everything is a file) 默认情 ...

  4. Linux System Programming 学习笔记(十) 信号

    1. 信号是软中断,提供处理异步事件的机制 异步事件可以是来源于系统外部(例如用户输入Ctrl-C)也可以来源于系统内(例如除0)   内核使用以下三种方法之一来处理信号: (1) 忽略该信号.SIG ...

  5. Linux System Programming 学习笔记(九) 内存管理

    1. 进程地址空间 Linux中,进程并不是直接操作物理内存地址,而是每个进程关联一个虚拟地址空间 内存页是memory management unit (MMU) 可以管理的最小地址单元 机器的体系 ...

  6. Linux System Programming 学习笔记(七) 线程

    1. Threading is the creation and management of multiple units of execution within a single process 二 ...

  7. Linux System Programming 学习笔记(六) 进程调度

    1. 进程调度 the process scheduler is the component of a kernel that selects which process to run next. 进 ...

  8. Linux System Programming 学习笔记(一) 介绍

    1. Linux系统编程的三大基石:系统调用.C语言库.C编译器 系统调用:内核向用户级程序提供服务的唯一接口.在i386中,用户级程序执行软件中断指令 INT n 之后切换至内核空间 用户程序通过寄 ...

  9. Linux System Programming 学习笔记(八) 文件和目录管理

    1. 文件和元数据 每个文件都是通过inode引用,每个inode索引节点都具有文件系统中唯一的inode number 一个inode索引节点是存储在Linux文件系统的磁盘介质上的物理对象,也是L ...

随机推荐

  1. mina架构在JT/T808协议应用程序中的应用

    Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP.UDP/IP协议栈的通信框架(当然,也可以提供JAVA 对象的序列化服务.虚拟机管道通信服务等),M ...

  2. oracle 将查询结果输出到txt文件里

    在查询语句里先输入spool filepath 中间是需要查询的语句,最后spool off 就会把中间查询的结果都输入到file文件里 spool E:\log.txt; select id,nam ...

  3. NSXMLParser

    NSXMLParser的使用 2011-05-05 15:50:17|  分类: 解析|字号 订阅     NSXMLParser解析xml格式的数据 用法如下: 首先,NSXMLParser必须继续 ...

  4. 转 Spring源码剖析——核心IOC容器原理

    Spring源码剖析——核心IOC容器原理 2016年08月05日 15:06:16 阅读数:8312 标签: spring源码ioc编程bean 更多 个人分类: Java https://blog ...

  5. Linux:FTP服务匿名用户,本地用户,虚拟用户配置

    匿名用户  FTP协议占用两个端口号: 21端口:命令控制,用于接收客户端执行的FTP命令. 20端口:数据传输,用于上传.下载文件数据. 实验:匿名访问,服务器192.168.10.10    客户 ...

  6. ThinkPHP5 高级查询之构建分组条件

    ThinkPHP5 高级查询之构建分组条件 一.在tp5中通过where方法如何构建分组条件, 例如:where user_id=$this->user_id and (status in (4 ...

  7. Fiddler证书安装不成功

    Fiddler 抓包https配置 提示creation of the root certificate was not successful 证书安装不成功 原文链接 在使用Fiddler抓包时,我 ...

  8. Linux学习-循环执行的例行性工作排程

    循环执行的例行性工作排程则是由 cron (crond) 这个系统服务来控制的.Linux 系统上面原本就有非常多的例行性工作,因此这个系统服务是默认启动的. 另外, 由于使用者自己也可以进行例行性工 ...

  9. Android兼容性测试CTS Verifier-环境搭建、测试执行、结果分析

    CTS Verifier算是CTS的一部分,需要手动进行,主要用于测试那些自动测试系统无法测试的功能,比如相机.传感器等.由于硬件配置或其他原因,不同手机上部分测试项目被隐藏,也就是说CTS Veri ...

  10. Python虚拟机函数机制之位置参数(四)

    位置参数的传递 前面我们已经分析了无参函数的调用过程,我们来看看Python是如何来实现带参函数的调用的.其实,基本的调用流程与无参函数一样,而不同的是,在调用带参函数时,Python虚拟机必须传递参 ...