Haskell, потребляем неблокирующий getLine - PullRequest
0 голосов
/ 28 мая 2020

Я ищу способ чтения из стандартного ввода и через некоторое время, если ввод не введен, я хочу пропустить этот getLine.

У меня есть этот код, который пропускает первую getLine через 3 секунды, но когда доходит до второй getLine, мне нужно ввести свой ввод дважды. Есть какие-нибудь советы?

main :: IO ()
main = do
  putStrLn "x:"
  x <- timeout 3000000 getLine
  putStrLn "y:"
  y <- getLine
  putStrLn y

1 Ответ

0 голосов
/ 30 мая 2020

Не полный ответ, но ...

Я могу подтвердить поведение на Windows. Появляется подсказка «x:», затем через 3 секунды появляется подсказка «y:», но первая строка ввода игнорируется. Если программа скомпилирована с -threaded, приглашение «y:» никогда не появляется, пока не будет введена первая строка. (Тайм-аут по-прежнему «обрабатывается» в том смысле, что значение x будет Nothing, если первая строка вводится после тайм-аута, но в любом случае, только вторая строка ввода обрабатывается для y <- getLine. )

Я думаю, что основная проблема может заключаться в проблемах с прерыванием ввода-вывода через асинхронные исключения в Windows, как описано в issue # 7353 . Отчет об ошибке там звучит так, как будто затронута только поточная среда выполнения, но я думаю, что проблема в том, используется ли поточная или непоточная среда выполнения. Реализация timeout имеет специальный путь кода для обработки потоковой среды выполнения Windows, что может объяснить различия в поведении, хотя в обоих случаях среда выполнения не может отменить первый getLine.

В настоящее время ведется работа над собственным Windows диспетчером ввода-вывода , который должен решить проблему № 7353 среди многих других проблем с вводом-выводом в Windows. У меня нет машины для сборки Windows, на которой я мог бы попытаться собрать / протестировать ее, чтобы проверить, решает ли она эту конкретную проблему c.

...