在过去的几年里,我一直在用不同的语言编写许多网络守护程序,现在我即将开始一个新项目,该项目需要专有网络协议的新自定义实现。
上述协议非常简单 - 一些基本的 JSON 格式的消息,这些消息以一些基本的帧包装形式传输,让客户端知道消息已完全到达并准备好进行解析。
该守护进程需要处理大量连接(同时大约 200 个)并对它们进行一些管理并传递消息,就像在聊天室中一样。
过去我主要使用 C++ 来编写我的守护进程。通常使用 Qt4 框架(网络部分,而不是 GUI 部分!),因为这也是我在其余项目中使用的,而且它易于操作且非常可移植。这通常工作得很好,而且我没有遇到太多麻烦。
作为一名 Linux 管理员已经有一段时间了,我注意到大多数网络守护进程都是用纯 C 语言编写的(当然也有一些是用其他语言编写的,但我感觉超过 80% 的网络守护进程都是用 C 语言编写的)守护进程是用纯 C 语言编写的)。
现在我想知道这是为什么。
这是由于纯粹的历史 UNIX 背景(如 KISS)还是为了简单的可移植性或减少膨胀?对于守护进程之类的东西,不使用 C++ 或任何“高级”语言的原因是什么?
提前致谢!
更新 1:
对我来说,使用 C++ 通常更方便,因为我的对象具有 getter 和 setter 方法等。纯 C 的“上下文”对象在某些时候可能会带来真正的痛苦 - 特别是当您习惯于面向对象编程时。
是的,我知道 C++ 是 C 的超集,并且 C 代码基本上是 C++ 您可以使用 C++ 编译器编译任何 C 代码。但这不是重点。 ;)
更新 2:
我知道现在使用 Python、node.js 或类似语言等高级(脚本)语言可能更有意义。我过去这样做过,并且我知道这样做的好处(至少我希望我这样做;) - 但这个问题只是关于 C 和 C++。
I've been writing a number of network daemons in different languages over the past years, and now I'm about to start a new project which requires a new custom implementation of a properitary network protocol.
The said protocol is pretty simple - some basic JSON formatted messages which are transmitted in some basic frame wrapping to have clients know that a message arrived completely and is ready to be parsed.
The daemon will need to handle a number of connections (about 200 at the same time) and do some management of them and pass messages along, like in a chat room.
In the past I've been using mostly C++ to write my daemons. Often with the Qt4 framework (the network parts, not the GUI parts!), because that's what I also used for the rest of the projects and it was simple to do and very portable. This usually worked just fine, and I didn't have much trouble.
Being a Linux administrator for a good while now, I noticed that most of the network daemons in the wild are written in plain C (of course some are written in other languages, too, but I get the feeling that > 80% of the daemons are written in plain C).
Now I wonder why that is.
Is this due to a pure historic UNIX background (like KISS) or for plain portability or reduction of bloat? What are the reasons to not use C++ or any "higher level" languages for things like daemons?
Thanks in advance!
Update 1:
For me using C++ usually is more convenient because of the fact that I have objects which have getter and setter methods and such. Plain C's "context" objects can be a real pain at some point - especially when you are used to object oriented programming.
Yes, I'm aware that C++ is a superset of C, and that C code is basically C++ you can compile any C code with a C++ compiler. But that's not the point. ;)
Update 2:
I'm aware that nowadays it might make more sense to use a high level (scripting) language like Python, node.js or similar. I did that in the past, and I know of the benefits of doing that (at least I hope I do ;) - but this question is just about C and C++.
发布评论
评论(8)
我想不出选择 C 而不是 C++ 的任何技术原因。无论如何,这不是我不能立即想到对位的。
编辑回复编辑:我会严重阻止您考虑“...C 代码基本上是 C++”。虽然从技术上讲,您可以使用 C++ 编译器编译任何 C 程序(只要您不使用 C 中比 C++ 采用的功能更新的任何功能),但我真的试图阻止任何人在 C++ 中编写类似 C 的代码或考虑使用 C++作为“带有对象的 C”。
对于 C 是 Linux 中的标准的回应,仅就 C 开发人员不断所说的而言:p C++ 与 C 一样是 Linux 中任何标准的一部分,并且在 Linux 上制作了各种各样的 C++ 程序。如果您正在编写 Linux 驱动程序,则需要使用 C 语言。除此之外...我知道 RMS 喜欢说您更有可能找到 C 编译器而不是 C++ 编译器,但实际上并没有很长一段时间以来都是如此。在几乎所有安装中,您都会发现两者或两者都没有。
针对可维护性——我当然不同意。
就像我说的,我想不出一个不能立即被反驳的。签证亦然。
I for one can't think of any technical reason to chose C over C++. Not one that I can't instantly think of a counterpoint for anyway.
Edit in reply to edit: I would seriously discourage you from considering, "...C code is basically C++." Although you can technically compile any C program with a C++ compiler (in as far as you don't use any feature in C that's newer than what C++ has adopted) I really try to discourage anyone from writing C like code in C++ or considering C++ as "C with objects."
In response to C being standard in Linux, only in as far as C developers keep saying it :p C++ is as much part of any standard in Linux as C is and there's a huge variety of C++ programs made on Linux. If you're writing a Linux driver, you need to be doing it in C. Beyond that...I know RMS likes to say you're more likely to find a C compiler than a C++ one but that hasn't actually been true for quite a long time now. You'll find both or neither on almost all installations.
In response to maintainability - I of course disagree.
Like I said, I can't think of one that can't instantly be refuted. Visa-versa too really.
对 C++ 开发守护程序代码的抵制源于以下几个方面:
C++ 因难以避免内存泄漏而闻名。对于任何长时间运行的软件来说,内存泄漏都是不允许的。这在一定程度上是不真实的——问题是具有 C 背景的开发人员倾向于在 C++ 中使用 C 习惯用法,这是非常有漏洞的。使用向量和智能指针等可用的 C++ 功能可以生成无泄漏代码。
相反,智能指针模板类虽然向程序员隐藏了资源分配和释放,但在幕后做了很多工作。事实上,由于复制构造函数等原因,C++ 通常有很多隐式分配。因此,随着时间的推移,C++ 堆可能会变得碎片化,即使有足够的 RAM,守护进程最终也会因内存不足错误而失败。这可以通过使用更能抵抗碎片的现代堆管理器来改善,但它们是通过预先消耗更多资源来实现的。
虽然这不适用于用户模式守护程序代码,但内核模式开发人员避免使用 C++,同样是因为 C++ 生成隐式代码,以及 C++ 库用于处理错误的异常。大多数c++编译器都是从硬件异常的角度来实现c++异常的,很多内核态代码都是在不允许抛出异常的环境中执行的。此外,所有由 C++ 生成的隐式代码(是隐式的)都不能包装在 #pragma 指令中以保证其放置在可分页或不可分页内存中。
因此,C++ 根本不可能在任何平台上进行内核开发,并且通常也被守护程序开发人员回避。即使代码是使用正确的智能内存管理类编写的并且不会泄漏 - 始终控制潜在的内存碎片问题使得内存分配显式的语言成为首选。
The resistance to C++ for the development for daemon code stem from a few sources:
C++ has a reputation for being hard to avoid memory leaks. And memory leaks are a no no in any long running software. This is to a degree untrue - the problem is developers with a C background tend to use C idioms in C++, and that is very leaky. Using the available C++ features like vectors and smart pointers can produce leak free code.
As a converse, the smart pointer template classes, while they hide resource allocation and deallocation from the programmer, do a lot of it under the covers. In fact C++ generally has a lot of implicit allocation as a result of copy constructors and so on. As a result the C++ heap can become fragmented over time and daemon processes will eventually fail with an out of memory error even though there is sufficient RAM. This can be ameliorated by the use of modern heap managers that are more fragmenttation resistant, but they do this by consuming more resource up front.
while this doesn't apply to usermode daemon code, kernel mode developers avoid C++, again because of the implicit code C++ generates, and the exceptions C++ libraries use to handle errors. Most c++ compilers implement c++ exceptions in terms of hardware exceptions, and lots of kernel mode code is executed in environments where exceptions are not allowed to be thrown. Also, all the implicit code generated by c++, being implicit, cannot be wrapped in #pragma directives to guarantee its placement in pageable, or non pageable memory.
As a result, C++ is not possible for kernel development on any platform at all, and generally shunned by daemon developers too. Even if one's code is written using the proper smart memory management classes and does not leak - keeping on top of potential memory fragmentation issues makes languages where memory allocation is explicit a preferred choice.
我会推荐您觉得更舒服的。如果您对 C++ 更熟悉,您的代码将会更干净,运行更高效,因为您会更习惯它,如果您明白我的意思的话。
这同样适用于更大范围的 Python 与 Perl 讨论之类的事情。无论您更熟悉哪个,都可能会生成更好的代码,因为您将拥有经验。
I would recommend whichever you feel more comfortable with. If you are more comfortable with C++, your code is going to be cleaner, and run more efficiently, as you'll be more used to it, if you know what I mean.
The same applies on a larger scale to something like a Python vs Perl discussion. Whichever you are more comfortable with will probably produce better code, because you'll have experience.
我认为原因是 ANSI C 是 Linux 中的标准编程语言。每当人们想要与他人共享代码等时,遵循此标准很重要。但如果您只想为自己编写一些东西,则这不是必需的。
您个人可以使用 C 或 C++,结果将是相同的。我认为如果您很了解 C++ 并且可以在代码中利用它的一些特殊的面向对象功能,您应该选择 C++。不要过多关注这里的其他人,如果您擅长 C++,只需用 C++ 编写您的守护程序即可。我个人也会用 C++ 编写它。
I think the reason is that ANSI C is the standard programming language in Linux. It is important to follow this standard whenever people want to share their code with others etc. But it is not a requirement if you just want to write something for yourself.
You personally can use C or C++ and the result will be identical. I think you should choose C++ if you know it well and can exploit some special object oriented features of it in your code. Don't look too much to other people here, if you are good in C++ just go and write your daemon in C++. I would personally write it in C++ as well.
你说得对。 不使用 C++ 的原因是 KISS,特别是如果您打算让其他人在以后维护您的代码。我认识的大多数人都是从现有资源或阅读史蒂文斯的书籍中学会编写守护程序的。几乎这意味着你的示例将使用 C 语言。C++ 就很好,我自己用它编写了守护进程,但我认为如果你希望它得到维护并且你不知道维护者可能是谁,那么显示出用 C 语言编写的更好的远见。
You're right. The reason for not using C++ is KISS, particularly if you ever intend for someone else to maintain your code down the road. Most folks that I know of learned to write daemons from existing source or reading books by Stevens. Pretty much that means your examples will be in C. C++ is just fine, I've written daemons in it myself, but I think if you expect it to be maintained and you don't know who the maintainer might be down the road it shows better foresight to write in C.
Boost 使得使用 asio 库。
Boost makes it incredibly easy to write single threaded, or multi-threaded and highly scalable, networking daemons with the asio library.
我建议使用 C++,但保留使用异常处理和动态 RTTI。这些功能可能会对运行时性能成本产生影响,并且可能无法跨平台得到很好的支持。
C++ 更加模块化和可维护,因此如果您可以避免这些功能,请继续将其用于您的项目。
I would recommend using C++, with a reservation on using exception handling and dynamic RTTI. These features may have run time performance cost implications and may not be supported well across platforms.
C++ is more modular and maintainable so if you can avoid these features go ahead and use it for your project.
C 和 C++ 都非常适合编写守护程序的任务。
除此之外,现在您还应该考虑 Perl 或 Python 等脚本语言。性能通常足够好,您将能够在更短的时间内编写更健壮的应用程序。
顺便说一句,看看 ACE,一个用于编写便携式网络应用程序的框架C++。
Both C and C++ are perfectly suited for the task of writing daemons.
Besides that, nowadays, you should consider also scripting languages as Perl or Python. Performance is usually just good enough and you will be able to write applications more robust and in less time.
BTW, take a look at ACE, a framework for writting portable network applications in C++.