printf行缓冲区的分析总结
最近在客户那调试串口的时候,read串口然后printf打印,单字符printf,发现没有输出,后来想起来printf这些标准输入输出函数也是属于标准C库glibc的,
这里就要区分一下标准库函数和系统调用了。
系统调用是内核提供给上层程序的接口,能够实现内核和上层之间的交互,系统调用在内核中的实现是软中断的方式,通过相应的中断服务例程来实现,而标准库函数是在系统调用的基础之上封装的应用程序,完全运行在用户态,在必要的时候调用系统调用。编写应用程序可以直接使用应用程序也可以使用库函数,那为什么还要有库函数呢。
以printf为例,在printf的实现中,在调用write之前加入了IO缓冲区,这是一个用户空间的缓冲,首先要说明一点,系统调用是软中断,频繁调用,需要内核频繁陷入内核态,这样的效率不是很高,而printf实际是向用户空间的IO缓冲写,在满足条件的情况下(条件下面会说)才会调用write系统调用,这样也就提高了内核的效率。
对于普通的文件操作,库函数因为IO缓冲区,效率高,其他方面与直接调用系统调用无异,但是对于一些特殊的文件,如串口终端以及网络设备。对于应用程序来将,我们更加希望的是每次的操作能够真真正正的反映在底层的硬件上,这时我们最好就不要使用类似与printf这样的带IO缓冲区的标准库函数了,而是直接使用系统调用,我上面就是犯了这个错误。
说完标准库函数和系统调用的区别,我们就要具体的分析一下printf。
printf是一个行缓冲函数,先写到缓冲区,满足条件后,才将缓冲区刷到对应文件中,刷缓冲区的条件如下:
1 缓冲区填满
2 写入的字符中有‘\n’ '\r'
3 调用fflush手动刷新缓冲区
4 调用scanf要从缓冲区中读取数据时,也会将缓冲区内的数据刷新
满足上面4个条件之一缓冲区就会刷新,,也就是printf会真正调用write来写入
当我们执行printf的进程或者线程结束的时候会主动调用flush来刷新缓冲区,所以程序结束,也会刷新
如果我们沦落到调用printf后再调用fflush来刷新的话,我感觉还不如调用write来的直接呢
其他的3点都好理解,下面我们就手动来研究一下printf的缓冲区到底有多大?
这就需要我们写一个小程序来验证一下,程序如下:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int i = 0x61;
while(1)
{
printf("%c", i);
i++;
i = (i - 0x61) % 26 + 0x61;
usleep(1000);
}
return 0;
}
在本地机器上编译这个程序,之后运行,在屏幕第一次输出结构后ctrl+C杀死,将结果保存在一个文件中,ls -l查看一下这个文件
我查看这个文件大小是1025个字节,这也就说明printf的缓冲区是1024byte,当写入第1025字节时刷新缓冲区到终端下。
printf行缓冲区的分析总结的更多相关文章
- W32Dasm缓冲区溢出分析【转载】
课程简介 在上次课程中与大家一起学习了编写通用的Shellcode,也提到会用一个实例来展示Shellcode的溢出. 那么本次课程中为大家准备了W32Dasm这款软件,并且是存在漏洞的版本.利用它的 ...
- 缓冲区溢出分析第08课:MS06-040漏洞研究——动态调试
前言 经过上次的分析,我们已经知道了MS06-040漏洞的本质,那么这次我们就通过编程实现漏洞的利用. 编写漏洞利用程序的框架 这里我使用的是VC++6.0进行编写,需要将包含有漏洞的netapi32 ...
- 缓冲区溢出分析第05课:编写通用的ShellCode
前言 我们这次的实验所要研究的是如何编写通用的ShellCode.可能大家会有疑惑,我们上次所编写的ShellCode已经能够很好地完成任务,哪里不通用了呢?其实这就是因为我们上次所编写的ShellC ...
- PA模块报错-实际返回的行数超出请求的行数(分析标准FORM报错解决思路)
录入预算报错时报错: 分析:这个错误是select into 语句返回多行的结果,但具体在哪? 两种方法查找,trace 或者debug 1.trace 启用调试 获取trace文件 -bash-3. ...
- fscanf_s与scanf_s的宽度参数与缓冲区参数分析
fscanf_s函数 在文件操作中经常会用到fscanf这个函数,但是在VC和VS中会有警告 意思是编译器觉得fscanf不安全,叫你考虑用一下fscanf_s这个函数来代替fscanf,fscanf ...
- 学机器学习,不会数据分析怎么行——数据可视化分析(matplotlib)
前言 前面两篇文章介绍了 python 中两大模块 pandas 和 numpy 的一些基本使用方法,然而,仅仅会处理数据还是不够的,我们需要学会怎么分析,毫无疑问,利用图表对数据进行分析是最容易的, ...
- 缓冲区溢出分析第10课:Winamp缓冲区溢出研究
前言 Winamp是一款非常经典的音乐播放软件,它于上世纪九十年代后期问世.与现在音乐播放软件行业百家争鸣的情况不同,当时可以说Winamp就是听音乐的唯一选择了,相信那个时代的电脑玩家是深有体会的. ...
- 缓冲区溢出分析第09课:MS06-040漏洞研究——深入挖掘
前言 经过前两次的分析,我们已经对Netapi32.dll文件中所包含的漏洞成功地实现了利用.在系统未打补丁之前,这确实是一个非常严重的漏洞,那么打了补丁之后,这个动态链接库是不是就安全了呢?答案是否 ...
- 缓冲区溢出分析第07课:MS06-040漏洞研究——静态分析
前言 我在之前的课程中讨论过W32Dasm这款软件中的漏洞分析与利用的方法,由于使用该软件的人群毕竟是小众群体,因此该漏洞的危害相对来说还是比较小的.但是如果漏洞出现在Windows系统中,那么情况就 ...
随机推荐
- mysql函数总结
MySQL函数 MySQL数据库提供了很多函数包括: 数学函数:字符串函数:日期和时间函数:条件判断函数:系统信息函数:加密函数:格式化函数: 一.数学函数 数学函数主要用于处理数字,包括整型.浮点数 ...
- 《零基础入门学习Python》【第一版】视频课后答案第006讲
python中被看作假:FALSE none 0 ‘ ’ " " ( ) [ ] { },其他一切都被解释为真 测试题答案: 0.Python 的 floor 除法现在使用 ...
- 剑指Offer(书):二叉树的镜像
题目:操作给定的二叉树,将其变换为源二叉树的镜像. public void Mirror(TreeNode root) { if (root == null) { return ; } if (roo ...
- PAT Basic 1015
1015 德才论 宋代史学家司马光在<资治通鉴>中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人.凡取人之术,苟不得圣人,君子而与之,与其 ...
- 【SaltStack】通过Master给Minion安装MySQL
一.IP信息说明 [Master] IP: 192.168.236.100 [Minion] IP: 192.168.236.101 二.配置SaltStack 关于SaltStack Master和 ...
- Python flask+css+js+ajax 综合复习
flask 基本语法结构 注:这里练习的时候把装饰器的@给忘记了,导致访问404 下面练习一下在前段向后端传递参数 get请求需要用 request.args.get('变量') 去接收, get ...
- Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). For example: Given binary tree {3,9,20,#,#,15,7}, 3 / \ 9 20 / \
class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vect ...
- xtu数据结构 C. Ultra-QuickSort
C. Ultra-QuickSort Time Limit: 7000ms Memory Limit: 65536KB 64-bit integer IO format: %lld Java ...
- POJ 2155 Matrix【二维线段树】
题目大意:给你一个全是0的N*N矩阵,每次有两种操作:1将矩阵中一个子矩阵置反,2.查询某个点是0还是1 思路:裸的二维线段树 #include<iostream>#include< ...
- BZOJ2246 [SDOI2011]迷宫探险 【记忆化搜索dp + 概率】
题目 输入格式 输出格式 仅包含一个数字,表示在执行最优策略时,人物活着走出迷宫的概率.四舍五入保留3位小数. 输入样例 4 3 3 2 .$. A#B A#C @@@ 143 37 335 85 9 ...