【问题标题】:can one make concurrent scalable reliable programs in C as in erlang?可以像在 erlang 中一样在 C 中制作并发可扩展的可靠程序吗?
【发布时间】:2010-10-14 09:28:12
【问题描述】:

一个理论问题。在阅读了 Armstrongs 的“programming erlang”一书后,我想知道以下几点: 学习 Erlang 需要一些时间。更别说掌握它了。它在很多方面确实有根本的不同。

所以我的问题是:是否可以编写“类似 erlang”或使用一些“类似 erlang 的框架”,考虑到您注意不要创建带有副作用的函数,您可以像在 Erlang 中一样创建可扩展的可靠应用程序吗?也许使用相同的消息发送,大量的“迷你进程”范例。

这样做的好处是不会把你积累的所有 C/C++ 知识抛到一边。

欢迎对此提出任何想法

【问题讨论】:

    标签: c++ concurrency erlang multicore


    【解决方案1】:

    我可以用一种图灵完备语言做的事情 我可以用任何其他图灵完备语言做。

    所以我将您的问题解读为:用 C++ 编写可靠且可扩展的应用程序是否像在 Erlang 中一样容易?

    这个问题的答案是非常主观的。对我来说,用 C++ 编写它更容易,原因如下:

    • 我已经用 C++ 做过(至少 3 次)。
    • 我不知道 Erlang。
    • 我读过很多关于 Stackless Python 的文章,我觉得它就像是一个高度并发的基于消息的 Python 协作多任务系统,但当然 Python 是在 C 之上编写的。

    话虽如此。如果您已经了解这两种语言,并且已经明确定义了问题,那么您可以根据手头的所有信息做出最佳选择。

    【讨论】:

    • 仅供参考:规范的 Python 解释器 CPython 是用 C 编写的,而不是 C++。
    • 您是否为您的 c 应用程序使用了框架?或者您是否也像以前的回复中建议的那样“重新发明轮子”?
    • @reinier:两者都是。我们编写了框架,然后在此之上构建。我们正在开发一个必须跨各种平台工作的框架/应用程序(早在 boost 之前),所以在某些情况下我们别无选择。现在事情变得容易了一些。 :)
    • 无堆栈 Python 使用“连续传递样式”(CPS)来获得高度灵活的代码路径(这就是它无堆栈的原因)。在那种写作风格上,获得并发几乎是微不足道的。困难的部分正在适应它。
    【解决方案2】:

    您显然可以 - Erlang/OTP 系统主要是用 C(和 Erlang)编写的。问题是“你为什么要这样做?”

    在过去,人们常常编写自己的操作系统 - 但您为什么要这样做?

    如果您选择使用操作系统,您的未编写软件具有某些属性 - 它可以保存在硬盘上,可以与网络通信,可以利用屏幕,它可以从命令行运行,它可以在批处理模式下调用等等......

    Erlang/OTP 系统有 150 万行代码,已被证明可以在大型系统(英国电话系统)中提供 99.9999999% 的正常运行时间 - 即每年 31 毫秒的停机时间。

    使用 Erlang/OTP,您的未编写软件具有高可靠性,它可以自行热插拔,您的未编写 > 应用程序可以在物理计算机死机时进行故障转移。

    您为什么要重写该功能?

    【讨论】:

    • 这很棒……但为什么它必须是一种全新的语言。如果有以下任何一种情况,那就太好了:a) 会有更多类似 c 语法的语言,可以在 erlang VM 中运行,或者 b) 会有一个 erlang 框架,你可以连接到 c 递归很棒,但也很好 mindf* **s
    • 它不是一种全新的语言——它是今年的第 14 届年度用户大会......它是一种成功且广泛使用的电信语言,它已经传播到互联网业务,因为它解决了以下问题可靠性和可扩展性很好。
    • true... 我的意思是从命令式语言程序员的角度来看。无论如何感谢您的洞察力。
    • Erlang/OTP 的函数式编程部分是其中最不重要的部分...您也可以将 C 与各种机制挂钩,请参阅互操作性教程 (erlang.org/doc/tutorial/part_frame.html )
    【解决方案3】:

    是的,有可能,但是...

    这个问题的最佳答案可能是罗伯特·维丁的第一条规则:

    “任何足够复杂的 另一种语言的并发程序 包含一个临时的, 非正式指定的,漏洞百出的,缓慢的 实现了一半的 Erlang。”

    非常好的规则是为任务使用正确的工具。 Erlang 在并发性和可靠性方面表现出色。 C/C++ 在设计时并未考虑到这些属性。

    如果你不想丢掉你的 C/C++ 知识和经验,并且你的项目允许这种划分,好的方法是创建一个 混合溶液。在 Erlang 中编写并发、通信和错误处理代码,然后添加 C/C++ 部分,这将执行 CPU 和 IO 绑定的事情。

    【讨论】:

    • AFAIK,原来的报价是关于 LISP 的。当然,任何人都会说它更适合他当时最喜欢的语言,但是(原始)LISP 的简约方法使它更“真实”
    • 不知道是关于 Lisp 的。谢谢,哈维尔
    • Its Greenspun's 10th Rule 一个具体的参考,即在任何足够大的项目中的某个时间点都会出现内部 DSL 来表达问题。很多时候,这最终会成为一种半生不熟的宏语言或一些通用的 execute(resolve(cobble())) 函数,它们是通过野蛮进化而出现的,新手无法理解。一半的观点是,Lisp 鼓励有意开发 DSL,以此来解决大多数语言似乎旨在防止这种情况的复杂性。
    【解决方案4】:

    使用 C(或 C++)编写可靠且易于扩展的程序的主要“问题”是在 C 中您可以做任何事情。所以,第一步是编写一个简单的框架,只限制一点。无论如何,大多数优秀的程序员都会这样做。

    在这种情况下,限制主要是为了在您想要的任何隔离级别内轻松定义“进程”。 fork() 以速度慢而著称,而且线程也需要大量时间来生成,因此您可能希望使用协作式多任务处理,这可能会更有效率,您甚至可以使其成为抢先式(我认为这就是 Erlang 所做的)。要获得多核效率,请设置一个线程池并让它们全部完成以运行任务。

    另一个重要的部分是创建一个适当的不可变数据结构库,以便使用它们(而不是标准库)您的函数将(大部分)无副作用。

    那么这只是为消息传递和未来设置一个好的 API 的问题......并不容易,但至少它看起来不像改变语言本身。

    【讨论】:

      【解决方案5】:

      是的,但你会做一些额外的工作。

      关于副作用,请考虑 .net/plinq 团队的处理方式。 Plinq 不能强制你交给它没有副作用的东西,但它会假设你这样做并遵守它的规则,所以我们可以使用更简单的 api。即使该语言没有对它的内置支持,它仍然会简化事情,因为您可以更轻松地破坏操作。

      【讨论】:

        【解决方案6】:

        我将把它分成 2 个问题

        您能否编写并发、可扩展的 C++ 应用程序

        是的。为了实现这一点,当然可以创建所需的低级构造。

        您想编写并发、可扩展的 C++ 应用程序

        也许吧。但是,如果我想要一个高度并发的应用程序,我会选择一种语言,要么旨在填补这一空白,要么很容易做到这一点(Erlang、F# 和可能的 C#)。

        C++ 不是为构建高度并发的应用程序而设计的。但它当然可以调整为这样做。但是,一旦考虑到内存管理,成本可能会比您预期的要高。

        【讨论】:

        • 为什么你更喜欢 C# 而不是 C++?例如,在 C++ 中,您可以执行诸如对齐缓存行上的共享数据结构之类的操作。
        • @RusselH,我的两个主要原因是内存管理和更好的线程支持。 C++ 支持线程,但在许多方面它是事后才想到的。 C# 设计了 ​​htreading 支持(尽管它在许多领域都缺乏)。
        • 我喜欢 c#,但我不明白为什么它使创建并发可扩展应用程序变得更容易。如果有的话,它隐藏了很多可能非常相关的细节。
        猜你喜欢
        • 1970-01-01
        • 2011-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多