“永远不被linux执行的程序”
扫描二维码
随时随地手机看文章
1. 前言
“我的人品有这么差吗!半个小时Linux都没调度我的线程!”。
前些日子同事抱怨,“linux是多线程系统,每个线程都有一个时间片,为什么我的程序似乎一直没被调度”,随即给我演示执行过程。大致归纳成下面的代码逻辑。
程序启动后仅仅输出一行“run”,然后就没有然后了,喝着咖啡、嗑着瓜子、带薪摸鱼,屏幕上干干净净。理想状态下每10秒执行任务完毕后输出“do”。
分析代码逻辑可知 “推断” 代码是否被运行的依据是屏幕上输出 “do” ,”而这真的科学吗?答案是否定的,linux有着雨露均沾的调度系统,很难做到半小时没被调度。问题就出在linux的 “行缓冲”机制 。
void main(){ printf("run\n"); while(1) { sleep(10); do_thing(); printf("do"); }}
上文的printf输出目标设备由STDOUT指定,STDOUT可能指向115200波特率的串口设备,也可能指向本地图形设备,相对于CPU而言他们的速度要慢上几个数量级。都是为了提高机器或者程序的性能、提高CPU利用率。协调高速设备和低速设备之间速度的不匹配,操作系统默认在标准I/O上采用行缓冲机制,printf的内容首先存储在内存,当缓冲填满或检测到换行符’’时则输出到目标设备。
Linux上这个行缓冲默认是1024Byte,每10s输出do占用2Byte,为了等待缓冲填满需要等待81min。
知道原理后解决方法就简单了。
方法1:fflush强制刷新标准输出stdout
void main(){ printf("run\n"); while(1) { sleep(10); do_thing(); fflush(stdout); printf("do"); }}
方法2:输出“换行符”
void main(){ printf("run\n"); while(1) { sleep(10); do_thing(); printf("do\n"); }}
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!