OCaml 适合编写网络服务器吗?

发布于 2024-09-09 08:56:40 字数 210 浏览 0 评论 0原文

我想知道在多线程环境中处理 TCP 上的典型客户端/服务器交互时,OCaml 是否会在性能和易于实现方面表现良好。我的意思是非常典型的事情,比如每个客户端都有一个线程来接收数据、操作更改游戏状态并将其发送回客户端。

这是因为我需要为游戏编写一个服务器,而且我总是用 C 语言做这些事情,但自从我知道 OCaml 以来,我很想知道它是否可以,否则我会发现自己试图解决一个典型的问题语言不太适合。

I was wondering if OCaml will perform well in terms of performance and ease of implementation while dealing with typical client/server interactions over TCP in a multi threaded environment.. I mean something really typical like having a thread per client that receives data, operated changes on game states and send them back to clients.

This because I need to write a server for a game and I always did these things in C but since now I know OCaml I was curious to know if it would be ok or I'll just find myself trying to solve a typical problem in a language that doesn't fit well that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

春风十里 2024-09-16 08:56:41

如果你想使用许多抢占式线程,Haskell 会是更好的选择。 GHC 可以支持大量线程,并且它们在多核系统上并行运行。 OCaml 更喜欢协作多线程和多进程。

Haskell would be a better choice if you want to use many preemptive threads. GHC can support huge numbers of threads and they run in parallel on multicore systems. OCaml prefers cooperative multithreading and multiple processes.

凉城凉梦凉人心 2024-09-16 08:56:40

性能:可能不会。 OCaml 的线程不提供并行执行,它们只是构建程序的一种方式。 OCaml 运行时本身不是线程安全的,因此唯一可能与单个 OCaml 线程并行执行的代码将是接口 C 代码(无需回调 OCaml!)。

在实现方面,运行时有一个互斥体,它在调用阻塞 C 原语时释放,也可以在调用执行重要工作的 C 函数时释放。

易于实施:它不会改变世界。您将享受到 OCaml 的便利以及类似 pthread 的库。如果您正在寻找新的发现,同时利用您所学到的 OCaml 知识,我推荐 Jocaml。它与 OCaml 同步和不同步,但最近有一个(重新)重新实现,即使它稍微不同步,它也很有趣,并且是并发程序的全新视角。

Jocaml 是在 OCaml 之上实现的。由于运行时不是并发的,我几乎可以肯定它使用单独的进程和消息传递。但对于你提到的应用程序来说,它应该能够做得很好。

Performance: probably not. OCaml's threads do not provide parallel execution, they are only a way to structure your program. The OCaml runtime itself is not thread-safe, so the only code that could possibly execute in parallel of a single OCaml thread would be interfaced C code (without callbacks to OCaml!).

Implementation-wise, there is a mutex on the run-time, which is released when calling blocking C primitives, and could also be released when calling C functions that do significant work.

Ease of implementation: it wouldn't be world-changing. You would have the comfort of OCaml and a pthread-like library on the side. If you are looking for new things to discover while leveraging what you have learnt of OCaml, I recommend Jocaml. It goes in and out of sync with OCaml, but there was a (re-)re-implementation quite recently, and even when it is slightly out of sync, it is a lot of fun, and a completely new perspective of concurrent programs.

Jocaml is implemented on top of OCaml. What with the run-time not being concurrent and all, I am almost sure it uses separate processes and message-passing. But for the application that you mentioned it should be able to do fine.

独木成林 2024-09-16 08:56:40

OCaml 非常适合编写网络服务器,尽管正如 Pascal 所观察到的,线程存在限制。

然而幸运的是,线程并不是组织此类程序的唯一方法。 Lwt 库(用于轻量级线程)提供了异步 I/O 的抽象,非常易于使用(特别是与一些语法支持结合使用时)。所有内容实际上都在一个线程中运行,但它都是由异步 I/O 循环(基于 Unix select 调用构建)驱动的,并且编程风格允许您编写看起来像直接代码的代码(避免了太多在许多其他语言中执行异步 I/O 的正常代码开销)。例如:

lwt my_message = read_message socket in
let repsonse = compute_response my_message in
send_response socket response

读取和写入都发生在主事件循环中,但是您可以避免正常的“读取,完成后调用此函数”手动开销。

OCaml is quite suitable for writing network servers, although as Pascal observes, there are limitations on threading.

Fortunately, however, threading isn't the only way to organize such a program. The Lwt library (for Light Weight Threads) provides an abstraction of asynchronous I/O that is quite easy to use (particularly when combined with a bit of syntax support). Everything actually runs in one thread, but it's all driven by an asynchronous I/O loop (built on the Unix select call), and the programming style lets you write code that looks like direct code (avoiding much of the normal code overhead of doing asynchronous I/O in many other languages). For example:

lwt my_message = read_message socket in
let repsonse = compute_response my_message in
send_response socket response

Both the read and the write happen back in the main event loop, but you avoid the normal "read, calling this function when you're done" manual overhead.

沙与沫 2024-09-16 08:56:40

我很抱歉这个问题已经在这里坐了八年了,我认为有几个非常糟糕的答案,因为他们都忽略了房间里的大象。

您说“非常典型,就像每个客户端都有一个线程”,但每个客户端都有一个操作系统线程是一个极其糟糕的设计。线程是重量级的,创建和销毁需要很长时间,仅线程堆栈就消耗约 1MB。如果每个连接有一个线程,那么 1,000 个并发客户端连接(这是完全可行的)将仅为其堆栈消耗 1GB RAM,并且程序(任何语言)的性能将因获取所需的上下文切换量而受到削弱。完成的任何工作。您不想在任何语言(包括 C 和 OCaml)中使用该设计。请注意,这个问题在跟踪垃圾收集语言的上下文中尤其严重,因为 GC 还会遍历所有这些线程堆栈,以便在每个 GC 周期之前整理全局根。我是第一个承认这种反模式在现实世界中普遍存在的人,但请不要复制它!我见过金融行业中用 C++ 编写的“低延迟”服务器,每个连接使用一个线程,并且仅从为这些线程提供服务的 (Windows) 操作系统中它们就遭受了长达六秒的延迟停顿。

请参阅:http://people.eecs .berkeley.edu/~sangjin/2012/12/21/epoll-vs-kqueue.html

让我们考虑一种高效的设计,例如操作系统内核的 epoll 或 kqueue 接口,为服务器提供有关传入和传出的代码信息。传出数据缓冲区。通过这种设计,单线程服务器可以获得优异的性能。然而,典型的服务器需要为每个客户端执行序列化工作,以及通常在所有客户端连接上串行执行的一些核心工作。因此,序列化和反序列化可以并行,但核心服务器操作不能并行。在这种情况下,OCaml 非常适合除序列化层之外的所有内容,因为它对并行性的支持很差。

我亲自为各个行业实现了许多服务器,性能要求差异很大。根据我的经验,OCaml 是最好的工具之一,因为它提供了出色的库(易于使用且可靠)和出色的串行性能。我遇到的唯一问题是并行化序列化层,但在实践中,我发现 OCaml 围绕 Java 和 .NET 等替代方案运行,尽管它们可以并行化。我发现 .NET 的典型延迟约为 100us,OCaml 的典型延迟为 10us。

另请参阅: http://prl.ccs.neu.edu/blog/2016/05/24/measuring-gc-latcies-in-haskell-ocaml-racket/

I'm so sorry this question has been sitting here for eight years with what I consider to be several quite bad answers because they all ignore the elephant in the room.

You say "really typical like having a thread per client" but having an OS thread per client is an extremely bad design. Threads are heavyweight, taking a long time to create and destroy and consuming ~1MB just for the thread stack. If you have one thread per connection then 1,000 simultaneous client connections (which is entirely feasible) will burn 1GB of RAM just for their stacks and the performance of your program (in any language) will be cripppled by the amount of context switching required to get any work done. You don't want to use that design in any language including both C and OCaml. Note that this problem is especially bad in the context of tracing garbage collected languages because the GC also traverses all of those thread stack in order to collate global roots before every GC cycle. I am the first to admit that this anti-pattern is ubiquitous in the real world but please don't copy it! I have seen "low latency" servers in the finance industry written in C++ using one thread per connection and they suffered latency stalls of up to six seconds just from the (Windows) OS servicing those threads.

See: http://people.eecs.berkeley.edu/~sangjin/2012/12/21/epoll-vs-kqueue.html

Let's consider an efficient design instead, like an epoll or kqueue interface to the OS kernel giving the server's code information about incoming and outgoing data buffers. Single threaded servers can attain excellent performance with this design. However, a typical server has serialization work to do per client and some core work that is often performed in serial across all client connections. Therefore, serialization and deserialization can be parallelized but the core server operation cannot. In this context, OCaml is great for everything except the serialization layer because it has poor support for parallelism.

I have personally implemented many servers for various industries with hugely varying performance requirements. In my experience, OCaml is one of the best tools for this because it offers excellent libraries (easy to use and reliable) and excellent serial performance. The only issue I have is around parallelizing the serialization layer but, in practice, I have found that OCaml runs circles around alternatives like Java and .NET even though they can parallelize this. I found typical latencies were ~100us for .NET and 10us for OCaml.

See also: http://prl.ccs.neu.edu/blog/2016/05/24/measuring-gc-latencies-in-haskell-ocaml-racket/

是你 2024-09-16 08:56:40

只要您能够接受一次相对较少数量的活动线程(例如不超过 100 个),OCaml 就非常适合网络应用程序。您可以考虑 MLdonkey 作为示例,尽管是在客户端空间,而不是在服务器空间。

OCaml will work great for networking applications as long as you can live with a relatively small number of threads active at one time—say no more than 100. You could consider MLdonkey as an example, although in the client space, not in the server space.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文