简体   繁体   English

动态流程池

[英]Dynamic pool of processes

I'm writing a client-server (TCP) program in C on a Unix system. 我正在Unix系统上用C编写一个客户端-服务器(TCP)程序。 The client sends some information and the server answers. 客户端发送一些信息,服务器回答。 There's only one connection per child process. 每个子进程只有一个连接。 New connections use pre-running processes from a pool, and the pool size is dynamic, so if the number of free processes (processes not servicing a client) drops too low, it should create new processes, and likewise if it gets too high extra processes should be terminated. 新的连接使用池中的预运行进程,并且池的大小是动态的,因此,如果空闲进程(不为客户端提供服务的进程)的数量减少得太少,则它应该创建新的进程,如果它变得过高,则同样会创建额外的进程进程应终止。

This is my server code. 这是我的服务器代码。 Every connection make a new child process using fork() . 每个连接都使用fork()创建一个新的子进程。 Each connection runs in a new process. 每个连接都在新进程中运行。 How can I make a dynamic pool like I explained above? 我如何像上面解释的那样建立一个动态池?

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);

} }

If you have several processes blocked in accept on the same listen socket, then a new connection that comes in will get delivered to one of them. 如果您在同一个侦听套接字上阻止了多个进程accept ,则进入的新连接将传递给其中一个。 (Depending, several may wake up, but only one will actually get the connection). (取决于,可能会唤醒几个,但实际上只有一个会连接)。 So you need to fork several children after listen , but before accept . 因此,您需要在listen之后但accept之前分叉几个孩子。 After handling a request, the child goes back to accept instead of exit . 处理完请求后,孩子返回accept而不是exit That handles (1) and (2). 处理(1)和(2)。

(3) is harder. (3)比较难。 You need some form of IPC. 您需要某种形式的IPC。 Typically, you'd have a parent process that just manages having the right number of children. 通常,您将拥有一个父进程,该进程仅负责管理正确数量的子进程。 Your child processes need to use IPC to tell the parent how busy they are. 您的子进程需要使用IPC来告诉父进程他们有多忙。 The parent can then either fork more children (which go into the accept loop above) or send signals to children to tell them to finish up and exit. 然后,父母可以分叉更多的孩子(进入上面的accept循环),也可以向孩子发送信号以告诉他们完成并退出。 It should also handle wait ing on children, handle unexpected deaths, etc. 它还应处理对孩子的wait ,处理意外死亡等。

The IPC you want to use is probably shared memory. 您要使用的IPC可能是共享内存。 Your two options are SysV ( shmget) and POSIX ( shm_open`) shared memory. 您的两个选项是SysV( shmget) and POSIX ( shm_open`)共享内存。 You probably want the latter if available. 如果可能,您可能需要后者。 You'll have to deal with synchronizing access (both POSIX and SysV provide semaphores to help with this, again prefer POSIX) or using atomic access only. 您将不得不处理同步访问(POSIX和SysV提供信号量来帮助解决此问题,再次偏爱POSIX)或仅使用原子访问。

(You probably don't actually want a process to exit the instant there are more than X free children, that'll lead to repeatedly reaping and spawning them, which is expensive. Instead you probably want some measure of how utilized they were over the last second... So your data is more complicated than a bitmap of in use/free.) (您实际上可能不希望有一个超过X个免费子级的进程立即退出,这会导致反复收获和生成它们,这很昂贵。相反,您可能想要某种程度的度量,以了解它们在整个过程中的利用率如何。最后一秒...因此,您的数据比正在使用/免费的位图更复杂。)

There are a lot of daemons that work like this, so you can fairly easily find code examples. 有许多这样的守护程序,因此您可以轻松地找到代码示例。 Of course, if you go look at Apache, you'll probably find it more complicated, to get good performance and be portable everywhere. 当然,如果您查看Apache,您可能会发现它更加复杂,从而获得良好的性能并可以随处移植。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM