Haskellからいくつかのファイル/ソケットを監視し、これらが読み取り/書き込み可能になるのを待つにはどうすればよいですか?
Haskellにselect/epoll / ...のようなものはありますか?または、ファイル/ソケットごとに1つのスレッドを生成し、常にそのスレッド内からブロッキングリソースを使用するように強制されますか?
Haskellからいくつかのファイル/ソケットを監視し、これらが読み取り/書き込み可能になるのを待つにはどうすればよいですか?
Haskellにselect/epoll / ...のようなものはありますか?または、ファイル/ソケットごとに1つのスレッドを生成し、常にそのスレッド内からブロッキングリソースを使用するように強制されますか?
質問は間違っています。ファイル/ソケットごとに1つのスレッドを生成してブロッキング呼び出しを使用する必要はなく、ファイル/ソケットごとに1つのスレッドを生成してブロッキング呼び出しを使用するようになります。これは(どの言語でも)最もクリーンなソリューションです。他の言語でそれを避ける唯一の理由は、そこでは少し非効率的であるということです。GHCのスレッドは十分に安価ですが、Haskellでは非効率的ではありません。(さらに、舞台裏では、GHCのIOマネージャーはepoll-alikeを使用して、必要に応じてスレッドをウェイクアップします。)
ラッパーがあります:https://hackage.haskell.org/package/select
ここでの使用例:select(2)
https ://github.com/pxqr/udev/blob/master/examples/monitor.hs#L36
ラッパーがありますpoll(2)
:
https ://hackage.haskell.org/package/poll
GHCベースには、Linux(および他のプラットフォームでは同等のもの)のepollをGHC.Event
モジュールにラップする機能が付属しています。
使用例:
import GHC.Event
import Data.Maybe (fromMaybe)
import Control.Concurrent (threadDelay)
main = do
fd <- getSomeFileDescriptorOfInterest
mgr <- fromMaybe (error "Must be compiled with -threaded") <$> getSystemEventManager
registerFd mgr (\fdkey event -> print event) fd evtRead OneShot
threadDelay 100000000
その他のドキュメントはhttp://hackage.haskell.org/package/base-4.11.1.0/docs/GHC-Event.htmlにあります
https://wiki.haskell.org/Simple_Servers#Epoll-based_event_callbacksにある古いバージョンのライブラリの使用例
ただし、loop
その例はその後、非表示のモジュールに移動GHC.Event.Manager
されており、私ができる限り公開されていません。教えて。GHC.Event
それ自体は「このモジュールはGHC内部と見なされるべきである」と述べています。
Control.Concurrent
とがthreadWaitRead
ありthreadWaitWrite
ます。したがって、上記のepollの例を翻訳するには:
import Control.Concurrent (threadWaitRead)
main = do
fd <- getSomeFileDescriptorOfInterest
threadWaitRead fd
putStrLn "Got a read ready event"
threadWaitRead
以降のIOアクションをラップして、Control.Monad.forever
それらを繰り返し実行できます。forkIO
プログラムが何か他のことをしている間に 、物をラップしてバックグラウンドで実行することもできます。