2

Additional to dynamic pool of process C

Changed code:

   int main(int argc, char *argv[])
    {
    ...//settings
    listensock = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
    result = bind(listensock, (struct sockaddr *) &sAddr, sizeof(sAddr));
    result = listen(listensock, 1);
    ...//skip errors checking

    while(1){
            newsock = accept(listensock, NULL,NULL);
            pid=fork();
            if (pid == 0) {
                send(newsock, buffer, nread, 0);
            }
            close(newsock);
    }
    wait(NULL);
}

This creates childs only if someone try to connect. It is not pre-fork model. N processes should be run after server starts and wait for connects. If I try to invoke fork() 3 times in loop, it immediately terminate. How to start, wait until someone connect and then send data (like in my code).

4

2 回答 2

4

在初始化之后,您可以将 移动到循环fork()之前。accept()listensock

for (int i = 0; i < 3; ++i) {
    int p = fork();
    if (p == 0) break;
    if (p < 0) { /* handle error... */ }
}
while (1) {
    newsock = accept(...);
    if (newsock < 0) { /* handle error... */ }
    else {
        send(newsock, ...);
        close(newsock);
    }
}
于 2013-04-30T15:23:31.820 回答
3

父进程不应该acceptselect在那个套接字上,当数据可用时,唤醒其中一个子进程。孩子会打电话accept

伪代码:

for (i = 0; i < 3; ++i) 
{
   if ((thepid=fork()))
   {
      while (1)
      {
       wait_for_signal();
       int newsock=accept();
       process_socket(newsock);
      }

   }
   else
      pids[i] = thepid;
}
while (1) 
{
   select(...);
   send_wakeup_signal(pids[random()%3]);
}

有几种方法可以发送唤醒信号(并等待一种)。一种方法是kill(pid, signal_number)pause()。但是,最终您需要将进程从就绪池中取出,并在完成后重新插入,因为有可能向正忙于处理先前请求的进程发送唤醒。这需要从孩子到父母的沟通。您可以使用命名管道或任何其他 IPC 机制来执行此操作。查看 Apache Web 服务器的源代码,了解该技术的典型工业强度示例。

于 2013-04-30T15:42:50.410 回答