print()函数函数 缓冲区是个什么东西了解缓冲区之后能怎样

 最近在客户那调试串口的时候read串口然后print()函数f打印,单字符print()函数f发现没有输出,后来想起来print()函数f这些标准输入输出函数也是属于标准C库glibc的

  这里就要区分一下标准库函數和系统调用了。

  系统调用是内核提供给上层程序的接口能够实现内核和上层之间的交互,系统调用在内核中的实现是软中断的方式通过相应的中断服务例程来实现,而标准库函数是在系统调用的基础之上封装的应用程序完全运行在用户态,在必要的时候调用系统调鼡编写应用程序可以直接使用应用程序也可以使用库函数,那为什么还要有库函数呢

  以print()函数f为例,在print()函数f的实现中在调用write之前加入叻IO缓冲区,这是一个用户空间的缓冲首先要说明一点,系统调用是软中断频繁调用,需要内核频繁陷入内核态这样的效率不是很高,而print()函数f实际是向用户空间的IO缓冲写在满足条件的情况下(条件下面会说)才会调用write系统调用,这样也就提高了内核的效率

   对于普通嘚文件操作,库函数因为IO缓冲区效率高,其他方面与直接调用系统调用无异但是对于一些特殊的文件,如串口终端以及网络设备对於应用程序来将,我们更加希望的是每次的操作能够真真正正的反映在底层的硬件上这时我们最好就不要使用类似与print()函数f这样的带IO缓冲區的标准库函数了,而是直接使用系统调用我上面就是犯了这个错误。

   说完标准库函数和系统调用的区别我们就要具体的分析一下print()函數f。

    print()函数f是一个行缓冲函数先写到缓冲区,满足条件后才将缓冲区刷到对应文件中,刷缓冲区的条件如下:

  满足上面4个条件之一缓冲區就会刷新,也就是print()函数f会真正调用write来写入

   当我们执行print()函数f的进程或者线程结束的时候会主动调用flush来刷新缓冲区所以程序结束,也会刷新

   如果我们沦落到调用print()函数f后再调用fflush来刷新的话我感觉还不如调用write来的直接呢

   其他的3点都好理解,下面我们就手动来研究一下print()函数f的緩冲区到底有多大

   这就需要我们写一个小程序来验证一下,程序如下:

在本地机器上编译这个程序之后运行,在屏幕第一次输出结构後ctrl+C杀死将结果保存在一个文件中,ls -l查看一下这个文件

 我查看这个文件大小是1025个字节这也就说明print()函数f的缓冲区是1024byte,当写入第1025字节时刷新緩冲区到终端下

  碰到的问题一段代码,print()函數在前log的在后,查看日志中log的反而在前面是python输出缓冲区的问题。

  python输出缓冲区要满 4k 才写入文件除非禁用缓存或者强制输出或者程序结束。中途 ctrl+c 中断会丢失一些输出

 最近在客户那调试串口的时候read串口然后print()函数f打印,单字符print()函数f发现没有输出,后来想起来print()函数f这些标准输入输出函数也是属于标准C库glibc的

  这里就要区分一下标准库函數和系统调用了。

  系统调用是内核提供给上层程序的接口能够实现内核和上层之间的交互,系统调用在内核中的实现是软中断的方式通过相应的中断服务例程来实现,而标准库函数是在系统调用的基础之上封装的应用程序完全运行在用户态,在必要的时候调用系统调鼡编写应用程序可以直接使用应用程序也可以使用库函数,那为什么还要有库函数呢

  以print()函数f为例,在print()函数f的实现中在调用write之前加入叻IO缓冲区,这是一个用户空间的缓冲首先要说明一点,系统调用是软中断频繁调用,需要内核频繁陷入内核态这样的效率不是很高,而print()函数f实际是向用户空间的IO缓冲写在满足条件的情况下(条件下面会说)才会调用write系统调用,这样也就提高了内核的效率

   对于普通嘚文件操作,库函数因为IO缓冲区效率高,其他方面与直接调用系统调用无异但是对于一些特殊的文件,如串口终端以及网络设备对於应用程序来将,我们更加希望的是每次的操作能够真真正正的反映在底层的硬件上这时我们最好就不要使用类似与print()函数f这样的带IO缓冲區的标准库函数了,而是直接使用系统调用我上面就是犯了这个错误。

   说完标准库函数和系统调用的区别我们就要具体的分析一下print()函數f。

    print()函数f是一个行缓冲函数先写到缓冲区,满足条件后才将缓冲区刷到对应文件中,刷缓冲区的条件如下:

  满足上面4个条件之一缓冲區就会刷新,也就是print()函数f会真正调用write来写入

   当我们执行print()函数f的进程或者线程结束的时候会主动调用flush来刷新缓冲区所以程序结束,也会刷新

   如果我们沦落到调用print()函数f后再调用fflush来刷新的话我感觉还不如调用write来的直接呢

   其他的3点都好理解,下面我们就手动来研究一下print()函数f的緩冲区到底有多大

   这就需要我们写一个小程序来验证一下,程序如下:

在本地机器上编译这个程序之后运行,在屏幕第一次输出结构後ctrl+C杀死将结果保存在一个文件中,ls -l查看一下这个文件

 我查看这个文件大小是1025个字节这也就说明print()函数f的缓冲区是1024byte,当写入第1025字节时刷新緩冲区到终端下

我要回帖

更多关于 print()函数 的文章

 

随机推荐