你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

linux的 “行缓冲”机制

[复制链接]
gaosmile 发布时间:2021-3-1 15:21
1. 前言
“我的人品有这么差吗!半个小时Linux都没调度我的线程!”。
前些日子同事抱怨,“linux是多线程系统,每个线程都有一个时间片,为什么我的程序似乎一直没被调度”,随即给我演示执行过程。大致归纳成下面的代码逻辑。
程序启动后仅仅输出一行“run”,然后就没有然后了,喝着咖啡、嗑着瓜子、带薪摸鱼,屏幕上干干净净。理想状态下每10秒执行任务完毕后输出“do”。
分析代码逻辑可知 “推断” 代码是否被运行的依据是屏幕上输出 “do” ,”而这真的科学吗?答案是否定的,linux有着雨露均沾的调度系统,很难做到半小时没被调度。问题就出在linux的 “行缓冲”机制
  1. # J8 J( C0 w2 ~7 a
  2. void main()
    # R% e0 ~; T& z/ u9 }* V. l$ [2 o7 k
  3. {
    - V9 b* a! I+ k; t7 G) N
  4.     printf("run\n");/ p5 r, J# U3 m4 }& V0 u
  5.     while(1) {3 h! E& i; f5 e; O( X# @
  6.         sleep(10);
    & o- m% g# |9 g1 ?4 ^& S6 C7 v
  7.         do_thing();
    % I7 Z0 ~  T- ~
  8.         printf("do");- g* m8 ~; J$ ~" v/ y" R
  9.     }$ z. l- g% R9 G" C$ f8 j5 z# R
  10. }
复制代码

7 q8 ]0 H: I  D) U

* z* W. K+ x" q) r" s5 B
2. 行缓冲

) c. f4 ?/ I4 [" w% r: N
上文的printf输出目标设备由STDOUT指定,STDOUT可能指向115200波特率的串口设备,也可能指向本地图形设备,相对于CPU而言他们的速度要慢上几个数量级。都是为了提高机器或者程序的性能、提高CPU利用率。协调高速设备和低速设备之间速度的不匹配,操作系统默认在标准I/O上采用行缓冲机制,printf的内容首先存储在内存,当缓冲填满或检测到换行符’’时则输出到目标设备
Linux上这个行缓冲默认是1024Byte,每10s输出do占用2Byte,为了等待缓冲填满需要等待81min。
知道原理后解决方法就简单了。
方法1:fflush强制刷新标准输出stdout

  1. 6 L, B! S7 K0 [- z- l2 ?. z
  2. #include
      f! n. F: h' @6 Y
  3. void main()
    / N; b2 C0 X, F- R$ o+ X  F
  4. {
    " ?& @# c0 H& }) f( w& U
  5.     printf("run\n");
    3 J$ |' U- \8 W* e
  6.     while(1) {
    . u& I7 |+ k! B# K
  7.         sleep(10);
    4 _6 z2 E0 A, q' h3 b: }
  8.         do_thing();4 @% J9 m3 b) R) ?+ r, a; w+ L
  9.         fflush(stdout);
    / L, t8 @3 ?; M$ r
  10.         printf("do");9 X( t( @& U7 Q# r+ O. E
  11.     }9 [: n# b0 K% D
  12. }
    . ^9 E* G0 r* k" C' p2 @* p
复制代码
6 e" V. n  G8 ^1 L7 ~/ _  d
方法2:输出“换行符”) k' v2 i% @3 c; Z4 H* ?9 ]

  1. # P1 Y( c' g0 d' U5 f: x; Z. c
  2. #include 1 X& N9 P5 V8 O  U  n% g
  3. void main()
    " t# F; V+ a* a4 n
  4. {. p+ L2 y$ w) E" _2 S
  5.     printf("run\n");! {& k6 @/ e: R* S+ a: [7 [
  6.     while(1) {; A) i: c* ~% y8 a3 F; M
  7.         sleep(10);
    ; {+ f! K8 b4 q' A1 R  h0 y1 q
  8.         do_thing();9 q% _. T$ p. e+ O
  9.         printf("do\n");3 v5 C7 M; T# K2 }% I6 I/ ^3 r9 d4 K3 j
  10.     }2 y5 v4 s. s8 r, s+ f
  11. }
复制代码

5 Y( W  `! i3 q8 U& c; H
收藏 评论0 发布时间:2021-3-1 15:21

举报

0个回答

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版