2012-01-11 28 views
0

我正在制作服务器,并使用fork()创建子进程,但我对此有所怀疑。这里有一些:有关分叉进程的问题

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

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

回答

1
  1. 套接字在Unix中的文件描述符,他们确实是整数,由用户所看到的,但他们确实是索引到内核每个进程维护一个表。在这个表中,每个文件描述符(FD)指的是开放文件描述(OFD),它们是在内核中维护的全系统对象。当你做fork()时,打开的文件描述符被复制,并且子节点和父节点都指向相同的OFD。有两个指向相同OFD的FD通常不是问题,但特别是对于插座,它们可能存在细微问题,因为只有在关闭指向它的FD时才会关闭连接。

  2. 你应该真的考虑使用线程(如果你使用线程,不要关闭套接字!)。 clone是一个Linux系统调用,不打算直接使用。你的选择是使用共享内存,但它有点复杂。

+0

这是非常翔实的。它确实很好地解释了套接字。现在很清楚。其实我有一些多线程的经验。我曾与pthreads工作,但叉似乎很好,因为你不需要另一个功能来做这件事。但是......我现在可能会使用pthread;) – Pijusn 2012-01-11 18:11:47

0

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

的分岔也有效地将所有内存(虽然在实践中这是写入时复制,所以它不是很贵)。除非您明确设置了一些共享内存,否则您将完成与父进程完全分离的新进程进程

也许你打算产生一个新的线程,而不是分叉新的进程

1
  1. int是一个句柄,但是套接字本身仍然与进程相关联。孩子主要出于安全原因关闭了监听套接字(它并不需要它,如果孩子产生了另一个进程,那么这个进程也会继承套接字)。服务器进程将关闭新连接的套接字,否则连接将保持打开状态,直到服务器进程退出(只要至少有一个进程仍然具有句柄,该套接字就存在)。

  2. 你要么需要多线程或正确的共享内存的方式。这是乐趣开始的地方。

独立进程之间

共享内存配备了有趣的问题,而且还提供否则无法能力(例如,您可以重新启动主服务器进程和离开进程服务运行,这是很难得到正确的开放连接两种不同版本的服务必须彼此交谈,但允许无缝升级而无需断开客户端连接或中断服务)。线程之间

共享内存是比较容易的,但是线程共享相同的一组文件描述符,这样你就不会赢得太多在这里。

最后,还有第三种选择:一个事件循环观看多个插槽,兼顾各只有东西是真正发生。查看selectpoll函数的文档。

0

我想你可能想通过this book作为fork()的参考。

  1. 是你需要关闭束缚在儿童和接受的套接字父听插座。整数aka文件句柄指向真实结构see this,因此除非您希望内核在可以将数据发送到连接的客户端的子代或父代上转储新连接,否则可能需要完全防止这种情况。
  2. 要共享进程之间的数据,最好的方法是共享内存。我提到你的这本书也会有相当多的信息。一般来说,如果你需要共享内存而没有共享内存,那么你可能想看看线程。

P.S.我不确定你指的是哪个clone()方法。对象复制通过复制构造函数完成。