Mag*_*nus 3 shell scheduling pipe
我有一个 Windows 命令行程序,我通过 wine 在 Ubuntu 中的 Bash 脚本中运行。Bash 脚本基本上是这样的:
wine myprogram.exe | while read line
do
# Process line
done
Run Code Online (Sandbox Code Playgroud)
现在,由于我已经编写了 myprogram.exe,我知道它只是尽可能快地输出数据。谁能向我解释一下 Bash while 循环如何处理数据,以防我的程序比 while 循环处理得更快?如果内核调度程序产生太多数据,内核调度程序会让 myprogram.exe 休眠吗?任何人?目前我倾向于它是黑魔法。
首先,程序可能会做自己的输出缓冲。这有时被称为“标准输入输出缓冲”的库组件执行此任务在C的名称之后:功能一样putc
,fputs
,fprintf
等,在宣布stdio.h
。如果是这样,它将产生突发输出,通常为几千字节(当输出是终端时,默认值是在每个换行符处刷新缓冲区)。
在某些时候,程序员或底层库函数会write
显式调用。这要求内核将指定的数据写入管道。内核可以决定写入全部或部分数据。由于文件是一个管道,内核会将数据复制到管道的缓冲区中。如果管道缓冲区已满,则write
系统调用将阻塞,直到有空间为止:您的程序(或者更准确地说,调用 的线程,write
以防有多个内核级线程)在调用write
返回之前不会恢复执行。
(有可能,但在这种情况下不太可能,程序将管道的文件描述符设置为non-blocking。如果是这种情况,如果内核确定它不能复制任何数据,它会将控制权返回给程序;write
系统调用返回 0。进行此类非阻塞系统调用的程序通常会调用select
或poll
或epoll
在循环中阻塞,直到它正在通信的文件描述符之一准备好输入或输出。)
程序在系统调用期间被阻塞的事实与调度算法的选择无关。从本质上讲,任何调度程序都会区分就绪线程(可以提供 CPU 时间)和等待线程(不能)。调度程序的要点是选择一个准备好的线程,让它运行直到线程进行系统调用(使线程进入等待状态)或发生一些异步事件(实际上是处理器中断)。在系统调用的处理过程中,可能是之前被阻塞的线程准备就绪,例如因为该线程处于write
调用,内核现在已经能够从该调用传递数据。一些事情可以使就绪线程从外部阻塞,例如暂停 ( SIGSTOP
)的信号。调度器维护某种就绪列表来决定接下来调度哪个线程:就绪线程列表(它通常比实际调度器中的简单列表复杂得多)。
归档时间: |
|
查看次数: |
4415 次 |
最近记录: |