異種のイベント セットを待機する必要があるサーバーのメイン ループを実装する一般的に受け入れられている方法は何ですか? つまり、サーバーは、次のいずれかが発生するまで (busywait ではなく) 待機する必要があります。
- 新しいソケット接続
- 既存のソケットで利用可能なデータ
- OS信号
- サードパーティ ライブラリのコールバック
異種のイベント セットを待機する必要があるサーバーのメイン ループを実装する一般的に受け入れられている方法は何ですか? つまり、サーバーは、次のいずれかが発生するまで (busywait ではなく) 待機する必要があります。
シングル スレッド、ノンブロッキング I/O、および select() 呼び出しを備えた C パラダイムの観点から考えていると思います。
Haskell でそのようなものを書くことはできますが、Haskell にはさらに多くの機能があります。
外界との接点ごとに新しいスレッドを作成し、すべてを STM で調整することをお勧めします。
と を使用takeMVar
しputMVar
て、スレッド間で同期します。操作が許可されていない場合、通常はスレッドをブロックします。ghc docsを読んでください。
最初に投稿された2つの解決策は、あなたが抱えている特定の問題に対してこれよりも優れていると思いますが、あなたが提示したタイプの問題を解決する方法は次のとおりです.
これを回避する簡単な方法は、次のような定義を取ることです
data SocketConn = ....
data DataAvail = ...
data OSSignal = ...
data Callback = ...
の単純化されていないバージョンを定義します
data ServerEvent = Sok SocketConn | Dat DataAvail | Sig OSSignal | Call Callback
handleEvent :: ServerEvent -> IO ()
handleEvent (Soc s) = ....
handleEvent (Dat d) = ....
handleEvent (Sig o) = ....
handleEvent (Call c) = ....
私が言うように、他の答えを読んでください!
Software Transactional Memory (STM) は、多方向待機を行う主な方法です。
ただし、見た目からすると、あなたのケースでは、タスクごとに個別の Haskell スレッドを生成し、何も起こらない間はそのような各スレッドをブロックさせたいだけでしょう。
1000 の OS スレッドを作成する必要はありませんが、1000 の Haskell スレッドはまったく問題ありません。
(これらのスレッドが時々調整する必要がある場合は、STM がおそらく最も簡単で信頼性の高い方法です。)