This question was migrated from Unix & Linux Stack Exchange because it can be answered on Stack Overflow. Migrated6年前。Learn more
我正在Unix系统上用C编写一个客户机服务器(TCP)程序。客户端发送一些信息,服务器应答。每个子进程只有一个连接。新连接使用来自池的预运行进程,池大小是动态的,因此,如果空闲进程(不为客户端提供服务的进程)的数量下降得太低,它应该创建新进程,同样,如果空闲进程太多,则应终止额外进程。
这是我的服务器代码。每个连接都使用fork()创建一个新的子进程。每个连接都在一个新进程中运行。我怎样才能像上面解释的那样创建一个动态池?
int main(int argc, char * argv[])
{
        int cfd;
        int listener = socket(AF_INET, SOCK_STREAM, 0); //create listener socket
        if(listener < 0){
            perror("socket error");
            return 1;
        }
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(PORT);
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
        int binding = bind(listener, (struct sockaddr *)&addr, sizeof(addr));
        if(binding < 0){
            perror("binding error");
            return 1;
        }
        listen(listener, 1); //listen for new clients
        signal(SIGCHLD,handler);
        int pid;

        for(;;) // infinity loop on server
        {
            cfd = accept(listener, NULL, NULL); //client socket descriptor
            pid = fork(); //make child proc
            if(pid == 0) //in child proc...
            {
                close(listener); //close listener socket descriptor
                ... //some server actions that I do.(receive or send)
                close(cfd); // close client fd
                return 0;
            }
            close(cfd);

}

最佳答案

如果您在同一个侦听套接字上的accept中有多个进程被阻塞,则传入的新连接将传递给其中一个进程。(视情况而定,可能会有几个人醒来,但实际上只有一个会得到连接)。因此,您需要在listen之后,但在accept之前叉几个孩子。处理完请求后,孩子将返回accept而不是exit。它处理(1)和(2)。
(3)更难。你需要某种形式的IPC。通常,您会有一个父进程,它只管理拥有正确数量的子进程。您的子进程需要使用IPC来告诉父进程有多忙。然后,父节点可以叉更多的孩子(进入上面的accept循环)或发送信号给孩子,告诉他们完成并退出。它还应该处理有关儿童的问题,处理意外死亡等。
您要使用的IPC可能是共享内存。您的两个选项是SysV(waitshm_open`)共享内存。如果有的话,你可能想要后者。您将不得不处理同步访问(POSIX和SysV都提供信号量来帮助实现这一点,还是更喜欢POSIX)或仅使用原子访问。
(你可能真的不希望一个进程在有超过X个孩子的瞬间退出,这将导致重复收割和产卵,这是昂贵的。相反,你可能想知道他们在最后一秒的利用率。。。因此,您的数据比正在使用/空闲的位图更复杂。)
有很多守护进程都是这样工作的,所以您可以很容易地找到代码示例。当然,如果您去看看Apache,您可能会发现它更加复杂,以获得良好的性能并在任何地方都是可移植的。

关于linux - 动态流程池,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16286208/

10-13 07:26