【问题标题】:Questions Related To Forking a Process与分叉进程相关的问题
【发布时间】:2012-01-11 17:19:34
【问题描述】:

我正在制作服务器,并使用 fork() 创建子进程,但我对此表示怀疑。以下是一些:

  1. 为什么需要在子进程中关闭主套接字,而在父进程中需要新的连接接受套接字? (接受新连接后)我认为套接字只是具有一些 id 的整数,用于访问某些系统范围对象中打开的套接字,这只能通过系统函数调用接受。在这种情况下,fork 只会复制整数,但不会影响打开的套接字。
  2. 我检查并发现如果我在类方法中派生一个进程,所有成员都会被复制。好吧,我发现它是编辑时复制,这是否意味着我的服务器类将被复制到每个使用非常量函数的子节点中?如何在所有此类进程之间共享一些内存(例如任务列表,每个孩子在父母从中读取内容时将内容放入其中)?我猜 fork 不是正确的功能。最好的方法是什么?

附:我很确定我知道第二个问题的答案,即 clone(),但只是想确保这是正确的函数。

【问题讨论】:

    标签: c++ c sockets fork


    【解决方案1】:
    1. Unix 中的套接字是文件描述符,在用户看来它们确实是整数,但它们实际上是内核为每个进程维护的表的索引。在此表中,每个文件描述符 (FD) 指的是一个打开文件描述 (OFD),它们是内核中维护的系统范围的对象。当您执行fork() 时,打开的文件描述符 是重复的,并且孩子和父母都指向同一个OFD。拥有两个引用同一个 OFD 的 FD 通常不是问题,但特别是对于套接字,它们可能会出现微妙的问题,因为只有当您关闭 所有引用它的 FD 时,连接才会关闭。

    2. 您应该真正考虑使用线程(如果您使用线程,请不要关闭套接字!)。 clone 是一个 linux 系统调用,不打算直接使用。您的替代方法是使用共享内存,但它有点复杂。

    【讨论】:

    • 这非常有用。它确实很好地解释了套接字的事情。现在很清楚了。其实我对多线程有一些经验。我曾使用过 pthreads,但 fork 看起来不错,因为您不需要另一个函数来做这件事。但是...我现在可能会使用 pthreads ;)
    【解决方案2】:
    1. int 是句柄,但套接字本身仍与进程关联。孩子关闭监听套接字主要是出于安全原因(它不需要它,如果孩子产生另一个进程,该进程也将继承套接字);服务器进程关闭新连接的套接字,否则连接将保持打开状态,直到服务器进程退出(只要至少有一个进程仍然拥有它的句柄,套接字就存在)。

    2. 您需要多线程或适当的共享内存方法。乐趣从这里开始。

    独立进程之间的共享内存带来了一些有趣的问题,但也提供了其他不可能的功能(例如,您可以重新启动主服务器进程并让服务于打开连接的进程保持运行,这很难解决,因为两个不同版本的然后服务必须相互通信,但允许无缝升级而无需断开客户端或中断服务)。

    线程之间共享内存相对容易,但是线程共享同一组文件描述符,所以在这里你赢不了多少。

    最后,还有第三种选择:一个事件循环监视多个套接字,只有在实际发生某些事情时才关注每个套接字。查看selectpoll 函数的文档。

    【讨论】:

      【解决方案3】:

      分叉重复的文件描述符,所以你必须关闭重复。

      分叉还可以有效地复制所有内存(尽管实际上它是写时复制,所以它不是很昂贵)。您创建了一个与父进程完全分离的新进程,除非您明确设置了一些共享内存。

      也许您打算生成一个新的线程而不是派生一个新的进程

      【讨论】:

        【解决方案4】:

        我认为您可能希望查看 this book 作为 fork() 的参考。

        1. 是的,您确实需要关闭绑定在子级中侦听的套接字并在父级中关闭已接受的套接字。整数又名文件句柄指向真实结构see this,因此除非您希望内核在能够将数据发送到连接客户端的子节点或父节点上转储新连接,否则您可能希望彻底阻止这种情况。
        2. 要在进程之间共享数据,最好的方法是共享内存。我推荐给你的那本书也会有很多关于这方面的信息。一般来说,如果您需要在没有共享内存的情况下共享内存,那么您可能需要查看线程。

        附:我不确定您指的是哪个 clone() 方法。对象复制是通过复制构造函数完成的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-12-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-13
          • 2011-08-16
          • 1970-01-01
          相关资源
          最近更新 更多