如何实现标准输入?

问题描述

在任何编程语言中,当我们要求用户输入时会发生什么?

比方说,在Haskell中,我们有以下代码

name <- getLine
putStrLn ("hey " ++ name)
 

getLine的实现会如何?

是否正确地假设,这会以某种方式侦听键盘中断,并在按下Enter键时函数停止执行?如果是这样,它将如何等待?有一段时间的循环吗?

解决方法

he。在现代计算机上,这实际上是一个相当复杂的问题。该按键需要经过大量计算,然后才能进入等待它的程序!

这是一个稍微简化的版本。

首先,程序向操作系统询问大量输入。如果自上次程序询问以来有输入,操作系统将立即返回该输入,并且您的程序将以自己的方式进行。如果没有,操作系统将挂起程序并将其放在特殊的监视列表中。然后,操作系统会切换到其他需要处理器时间的程序,或者,如果当前没有任何程序,则会使计算机进入休眠状态几秒钟。计算机将继续正常运行,处理其他程序并在没有可用程序时进入睡眠状态,直到操作系统检测到应该输入到程序的键盘输入为止。完成后,它将查询其监视列表,唤醒您的进程,并使用收到的输入将控制权返回给您的程序。

所以这是一个循环:操作系统在等待各种事物(包括那些等待更多计算时间的事物)的程序列表上循环,直到接收到键盘输入为止。然后在程序中有第二个循环,该循环不断要求输入更多的块,直到其中一个包含换行符为止。

重要的是要知道两个循环,而不仅仅是说“是的,程序中有一个等待的循环”,原因是:由于采用了这种架构,您的程序不需要实现暂停计算的逻辑直到键盘中断触发。等待该中断的循环全部在操作系统中实现。

,

getLine的实现如何?

假设以某种方式侦听键盘中断并按下Enter键,该函数停止执行是正确的吗?

大多数语言的getLine函数的程序员通常不需要关心中断甚至是等待。 Haskell有点特殊,但是在大多数语言中,伪代码基本上可以看起来像这样:

loop:
  ask the OS for 1 character
  if reached EOF or Enter:
     return the string
  append character to the string

向OS询问字符的形式为调用OS提供的函数(syscall)read(myInputSource,myBufferSpace,maxBytesToRead)。直到有字符可用时,该函数才会返回,因此getLine程序员甚至不必添加等待。

真正的操作系统要提供此read()功能必须经历的过程令人着迷且复杂(并且是a common interview question的基础)。但是,撰写getLine的人只需要相信操作系统就能完成工作。