在接受连接之前或之后分叉?
问题描述:
以下代码片段创建4个进程,全部共享相同的侦听套接字。在接受连接之前或之后分叉?
这样做有没有危险?在传统方式下,我是否应该在接受连接后始终有一个监听流程和分支?
for (p = 0; p < 3; p++) {
pid = fork();
if (pid == 0) break;
}
while (1) {
unsigned int clientlen = sizeof(echoclient);
/* Wait for client connection */
if ((clientsock =
accept(serversock, (struct sockaddr *) &echoclient,
&clientlen)) < 0) {
die("Failed to accept client connection");
}
fprintf(stdout, "Process No. %d - Client connected: %s\n",
p,
inet_ntoa(echoclient.sin_addr));
handle_client(clientsock);
}
(我的理解,接受后分叉允许程序,使每个连接的过程。我与原线程和各种异步的东西玩耍,所以我只是在寻找具有核心每一个进程)
答
你可以这样做。
正如你所看到的,接受后的分叉是每个客户端/连接的一个孩子。接受之前分岔(但听后)通常称为预分岔。每个孩子都会等待接受,并且无论哪个孩子都会接受传入的连接。这是安全的,只要接受是由内核完成的(我认为)任何现代的unix都可以。如果不是这样,你必须在接受处添加某种IPC(互斥锁等)。预分叉的好处是你不需要为每个连接花费一个分支,你已经拥有一个现有的分支。
我虽然是内核职责,执行TCP层背后的引擎盖(又名树方式柄摇)接受tcp连接。我确定这里不需要IPC。 SO上的某人是否知道它在哪里? – 2009-10-14 21:54:06
据史蒂文斯说,BSD派生的内核总是这样做。一些较旧的SysV系统在库中实现接受并且需要锁定。可疑的是,任何人都在运行一个旧的生产操作系统,但我想你永远不知道。 – Duck 2009-10-14 22:36:18
如果我们使用pre-fork,我们不需要Linux上的setsockopt(server_fd,REUSEPORT),对吧?@Duck – 2017-02-28 13:55:33