【问题标题】:Create a new thin process, fork or threads?创建一个新的瘦进程、fork 或线程?
【发布时间】:2018-10-20 01:00:11
【问题描述】:

我正在做一个小项目,正在寻求建议。

基本上,我有一个主进程,它是一个服务器,具有各种动态增长的数据结构和一些套接字。

在某些情况下,我需要创建运行小循环的进程(它们不需要任何数据结构、主服务器的 fd 或套接字)。 一个重要的要求是它们应该:快速、轻便和耐用(即使主服务器被杀)。

fork:我会随着时间的推移获得持久性,但复制主服务器意味着复制其所有数据结构、fd 等,这会不必要地加重新进程的负担。

线程:轻巧快速但不耐用,最重要的是非常不稳定(如果线程由于某种原因产生错误可能会阻塞一切)。

理想的情况是一个神奇的系统调用,它执行一个 ex novo 进程,该进程具有一个作为入口点的函数,但我认为没有这样的东西。

你对我有什么建议吗?

【问题讨论】:

  • 既然你说“他们不需要主服务器的任何数据结构,fd或socket”,那么fork一个新进程不会太贵。当你 fork 时它不会复制所有内容,它会 copy on write
  • @TianjiaoHuang:父母的内存也会被标记为copy-on-write,所以fork可能没那么便宜。
  • fork 是“耐用”的唯一选择。是否可以选择保持一些从属进程运行并通过 IPC 向它们发出命令? (管道、套接字、共享内存...)
  • 看看你的设计。之间的任何通信。如果您的设计依赖于大数据项的频繁信号发送,那么线程将更加高效,因为您可以发送指针信号而不是复制批量数据。但是,如果存在相当程度的数据隔离,那么线程相对于进程几乎没有优势。课程用马。
  • ..或者你可以采取务实的方法来设计你的系统,这样你就可以轻松地尝试两者,然后只是测试。

标签: c linux multithreading pthreads fork


【解决方案1】:

fork:我会随着时间的推移获得持久性,但复制主服务器意味着 复制它的所有数据结构,fd 等,这会拖累新的 不必要的处理。

没有你想象的那么多。 Linux fork() 长期以来一直通过写时复制页面实现。子进程将拥有与父进程相同的地址空间,但它不会拥有自己的任何两个进程都不会修改的页面的副本。此外,复制修改页面的成本会随着时间的推移而摊销。最初的fork() 相当便宜。

线程:轻巧快速但不耐用,最重要的是非常不稳定(如果 一个线程由于某种原因产生一个错误可能会阻塞一切)。

鉴于该分析,线程毕竟不是一个真正的选择。耐用性和稳定性是功能要求。最小重量和在某种程度上甚至速度都是效率问题。前者几乎每次都胜过后者。

理想的事情是一个神奇的系统调用,它执行一个从头开始 具有作为入口点的功能的过程,但我认为有 不是那样的。

由于您的目标是 Linux,您是否考虑过clone()?它完全符合您的描述,但我怀疑您所说的是否完全捕捉了您为此类功能想象的语义。

或者,您是否考虑过 fork + exec?这可能需要进行一些重构,但是通过执行 exec,子进程会在(便宜的)初始分叉之后尽可能多地摆脱与其父进程共享的上下文。

【讨论】:

  • 克隆:它可能是一个解决方案,但使用哪些标志来尽可能少地继承?据我了解,clone 的行为类似于 fork,它复制了进程,并可选择共享其执行上下文的哪一部分。 Fork + exec 解决方案在我的情况下似乎是最好的,但我想避免生成单独的可执行文件。
  • 正如我所说,@alessiovolpe,我怀疑您所写的内容是否完全符合您的想法。克隆 确实 的行为类似于 fork。如果您仔细阅读标志列表,您会发现几乎所有这些都要求与原始进程进行更多共享,因此不指定标志可以让您尽可能少地共享。但是没有共享意味着 复制 (在适用的情况下使用写时复制,如 fork)。但是你得到指定的函数作为入口点,并从它返回终止子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-20
  • 1970-01-01
  • 2023-03-22
相关资源
最近更新 更多