【问题标题】:Implement main server loop in Haskell?在 Haskell 中实现主服务器循环?
【发布时间】:2012-09-13 19:08:11
【问题描述】:

实现需要等待异构事件集的服务器的主循环的普遍接受的方法是什么?那就是服务器应该等待(不是busywait),直到发生以下情况之一:

  • 新的套接字连接
  • 现有套接字上的可用数据
  • 操作系统信号
  • 第三方库回调

【问题讨论】:

    标签: haskell


    【解决方案1】:

    我认为您正在考虑具有单线程、非阻塞 I/O 和 select() 调用的 C 范例。

    您可以设法在 Haskell 中编写类似的东西,但 Haskell 可以提供更多功能:

    我建议您为与外界的每个单独的接触点创建一个新线程,并保持一切与 STM 协调。

    【讨论】:

      【解决方案2】:

      使用takeMVarputMVar 在线程之间进行同步。如果不允许操作,它们通常会阻塞线程。 阅读ghc docs

      【讨论】:

      • Chan。我真的很喜欢Chan
      【解决方案3】:

      我想明确表示,对于您遇到的特定问题,我认为首先发布的两个解决方案比这个更好,但这里有一种方法可以解决您提出的问题类型。

      解决这个问题的一种简单方法是将您的定义视为

      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) = ....
      

      就像我说的,阅读其他答案!

      【讨论】:

      • 你不应该这么谴责这个答案;这是做事的合法方式。它确实回答了潜在的普遍问题,即“如何处理所有输入相同槽的不同形状的可能性?”。正如您所建议的,答案是“使用标记的联合”。
      • @DanBurton 好的,我已经将“不要这样做”淡化为“其他解决方案更适合您的特定问题”
      【解决方案4】:

      软件事务内存 (STM) 是进行多路等待的主要方式。

      但是,从外观上看,在您的情况下,您可能只想为每个任务生成一个单独的 Haskell 线程,并让每个这样的线程在没有任何事情发生时阻塞。

      你不会想创建一千个操作系统线程,但一千个 Haskell 线程一点也不麻烦。

      (如果这些线程需要不时协调,那么再次,STM 可能是最简单、最可靠的方法。)

      【讨论】:

        猜你喜欢
        • 2013-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多