2009-10-14 27 views
8

以下代码片段创建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); 
} 

(我的理解,接受后分叉允许程序,使每个连接的过程。我与原线程和各种异步的东西玩耍,所以我只是在寻找具有核心每一个进程)

回答

10

你可以这样做。

正如你所看到的,接受后的分叉是每个客户端/连接的一个孩子。接受之前分岔(但听后)通常称为预分岔。每个孩子都会等待接受,并且无论哪个孩子都会接受传入的连接。这是安全的,只要接受是由内核完成的(我认为)任何现代的unix都可以。如果不是这样,你必须在接受处添加某种IPC(互斥锁等)。预分叉的好处是你不需要为每个连接花费一个分支,你已经拥有一个现有的分支。

+0

我虽然是内核职责,执行TCP层背后的引擎盖(又名树方式柄摇)接受tcp连接。我确定这里不需要IPC。 SO上的某人是否知道它在哪里? – 2009-10-14 21:54:06

+6

据史蒂文斯说,BSD派生的内核总是这样做。一些较旧的SysV系统在库中实现接受并且需要锁定。可疑的是,任何人都在运行一个旧的生产操作系统,但我想你永远不知道。 – Duck 2009-10-14 22:36:18

+0

如果我们使用pre-fork,我们不需要Linux上的setsockopt(server_fd,REUSEPORT),对吧?@Duck – 2017-02-28 13:55:33

相关问题