Chr*_*ton 3 c io internals getchar
我已经包含了一个使用getchar()下面的示例程序,供参考(并非任何人都可能需要它),如果您愿意,可以随意解决它的问题.但我的问题是:
程序调用时究竟发生了什么getchar()?
以下是我的理解(请澄清或纠正我):
我使用的术语可能不太正确.
#include <stdio.h>
int getLine(char buffer[], int maxChars);
#define MAX_LINE_LENGTH 80
int main(void){
char line[MAX_LINE_LENGTH];
int errorCode;
errorCode = getLine(line, sizeof(line));
if(errorCode == 1)
printf("Input exceeded maximum line length of %d characters.\n", MAX_LINE_LENGTH);
printf("%s\n", line);
return 0;
}
int getLine(char buffer[], int maxChars){
int c, i = 0;
while((c = getchar()) != EOF && c != '\n' && i < maxChars - 1)
buffer[i++] = c;
buffer[i++] = '\0';
if(i == maxChars)
return 1;
else
return 0;
}
Run Code Online (Sandbox Code Playgroud)
步骤2-4稍微关闭.
如果标准I/O缓冲区中没有输入,则getchar()调用函数重新加载缓冲区.在类Unix系统上,通常最终调用read()系统调用,read()系统调用将进程置于睡眠状态,直到有待处理的输入,或者内核知道没有要处理的输入(EOF).当读取返回时,代码调整数据结构,以便getchar()知道可用的数据量.你的描述意味着民意调查; 标准I/O系统不会轮询输入.
步骤5使用调整后的指针返回正确的值.
真的没有EOF角色; 它是一个国家,而不是一个角色.即使您键入Control-D或Control-Z指示"EOF",该字符也不会插入到输入流中.实际上,这些字符会导致系统刷新仍在等待"行编辑"操作的任何类型字符(如退格键)以更改它们,以便它们可供read()系统调用使用.如果没有这样的字符,则read()返回0作为可用字符的数量,这意味着EOF.然后getchar()返回值EOF(通常-1但保证为负值,而有效字符保证为非负值(零或正)).
因此,基本上,而不是轮询,是命中Return导致某个I/O中断,然后当操作系统收到这个时,它会唤醒任何为I/O休眠的进程?
是的,命中Return触发中断,操作系统内核处理它们并唤醒正在等待数据的进程.当中断发生时,内核会唤醒终端驱动程序,并决定如何处理刚收到的字符.它们可能被藏匿以进行进一步处理(规范模式)或立即可用(原始模式)等.当然,假设输入是终端; 如果输入来自磁盘文件,它在很多方面更简单 - 或者如果它是管道,或者......
名义上,终止应用程序不会被中断唤醒; 它是首先唤醒的内核,然后在终端应用程序中运行的shell被唤醒,因为它有数据供它读取,并且只有在输出时终端应用程序被唤醒.
我说"名义上"因为有一个外部机会实际上终端应用程序确实通过pty(伪tty)调解I/O,但我认为它发生在内核级别并且终端应用程序涉及到相当晚处理.键入的键盘和键入的显示器之间存在巨大的脱节.
另请参见Canonical与非规范终端输入.