问题描述
在任何编程语言中,当我们要求用户输入时会发生什么?
比方说,在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
的人只需要相信操作系统就能完成工作。