Неблокирующее IO с Haskell [дубликат]
Возможный дубликат:
какова реакция Хаскелла на узел?js?
Как я могу смотреть несколько файлов / сокетов, чтобы стать читаемым/доступным для записи в Haskell?
Можно ли написать программу Haskell, которая выполняет ввод-вывод неблокирующим способом, как в nodejs?
Например, я хотел бы получить 10 записей из базы данных, которая находится далеко, поэтому я хотел бы запустить 10 запросов одновременно, и когда результат будет доступен, то верните эту коллекцию. Монада IO не поможет, потому что монада явно сериализует вычисления с помощью bind. Я думаю, что стиль передачи продолжения, в котором вы передаете вычисление, которое вы хотите затем, имеет ту же проблему, снова он сериализует вычисление. Я не хочу работать с потоками, я ищу другое решение. Возможно ли это?
2 ответа:
Нити Хаскелла имеют чрезвычайно малый вес. Более того, GHCs IO monad большую часть времени использует событийное планирование, что означает, что обычный код Хаскелла похож на узел стиля передачи продолжения.JS-код (компилируется только в машинный код и выполняется с несколькими процессорами...)
Ваш пример тривиален
import Control.Concurrent.Async --given a list of requests requests :: [IO Foo] --you can run them concurrently getRequests :: IO [Foo] getRequests = mapConcurrently id requests
Control.Concurrent.Async
Вероятно, это именно то, что вы ищете в отношении библиотеки для будущего. Хаскелл никогда не должен задыхаться от простых тысяч (обычных) нитей. Я никогда этого не делал. написан код, который использует миллионы потоков ввода-вывода, но я думаю, что ваши единственные проблемы будут связаны с памятью.
Чтобы конкретизировать комментарии к
Control.Concurrent.Async
, Вот пример использованияasync
пакет.Таким образом, в приведенном выше примере мы определяем три запроса HTTP get для трех различных веб-сайтов, запускаем эти запросы асинхронно и ждем завершения всех трех, прежде чем продолжить.import Network.HTTP.Conduit import Control.Concurrent.Async main = do xs <- mapM (async . simpleHttp) [ "www.stackoverflow.com" , "www.lwn.net" , "www.reddit.com/r/linux_gaming"] [so,lwn,lg] <- mapM wait xs -- parse these how ever you'd like