10

Haskellからいくつかのファイル/ソケットを監視し、これらが読み取り/書き込み可能になるのを待つにはどうすればよいですか?

Haskellにselect/epoll / ...のようなものはありますか?または、ファイル/ソケットごとに1つのスレッドを生成し、常にそのスレッド内からブロッキングリソースを使用するように強制されますか?

4

2 に答える 2

15

質問は間違っています。ファイル/ソケットごとに1つのスレッドを生成してブロッキング呼び出しを使用する必要はなく、ファイル/ソケットごとに1つのスレッドを生成してブロッキング呼び出しを使用するようなります。これは(どの言語でも)最もクリーンなソリューションです。他の言語でそれを避ける唯一の理由は、そこでは少し非効率的であるということです。GHCのスレッドは十分に安価ですが、Haskellでは非効率的ではありません。(さらに、舞台裏では、GHCのIOマネージャーはepoll-alikeを使用して、必要に応じてスレッドをウェイクアップします。)

于 2012-07-31T16:27:09.190 に答える
4

ラッパーがあります: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プログラムが何か他のことをしている間に 、物をラップしてバックグラウンドで実行することもできます。

于 2018-05-17T05:15:39.010 に答える