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. thinkphp的使用——隐藏index.php

    官方默认的.htaccess文件 <IfModule mod_rewrite.c>  Options +FollowSymlinks -Multiviews  RewriteEngine ...

  2. Dojo的on函数(以前的dojo.connect)

    ​同jQuery的on函数: require(["esri/map", "dojo/on"], function(Map, on) { // ... on(my ...

  3. java基础—基础语法1

    一.标识符

  4. k8s的资源限制及资源请求

    容器的资源需求及限制:  需求:requests   ##定义容器运行时至少需要资源  限制:limits     ##定义容器运行时最多能分配的资源    requests:pod.spec.con ...

  5. jQuery发送ajax请求实现跨域访问

    Java代码的话,在返回响应之前调用如下代码中的allowCrossDomainAccess()方法: /** * 允许跨域访问 */ public void allowCrossDomainAcce ...

  6. 【jquery】 选中复选框 和 return false 的影响

    $('id').attr('checked',true); return false;   如果后面接上return false 的话,复选框的钩钩不会改变,但是.is(':checked')仍然能检 ...

  7. Linux安装OpenCV

    sudo apt-get update sudo apt-get install git git clone https://github.com/jayrambhia/Install-OpenCV ...

  8. selenium2常用API介绍

    我们模拟web操作都是基于元素来操作的,我们首先要先确定元素,然后这个元素下对应的方法就可以看WebElement的方法. 1.点击操作 WebElement button=driver.findEl ...

  9. CodeForces Round #320 Div2

    A. Raising Bacteria 计算一下x的bitcount就是答案. #include <iostream> #include <cstdio> #include & ...

  10. idea Live Template 快速使用

    善用LiveTemplates,好用到没朋友,我凑揍 , 尊重原创,原文链接: https://blog.csdn.net/u012721933/article/details/52461103#co ...