繁体   English   中英

流程C的动态池

[英]dynamic pool of process C

我在UNIX上用UNIX编写程序。我必须在套接字上编写客户端 - 服务器(TCP)程序。 客户端发送一些信息和服务器答案。 无论客户端发送或接收什么,因为我成功为其编写代码。 但是最后一部分任务对我来说非常困难。

1)一个连接 - 一个子进程。

2)对于使用池中预运行进程的新连接。

3)池大小是dinamic。如果自由进程(不服务客户端)的数量变得小于N - 应创建新进程,如果它变得超过K - 必须终止“额外”进程。

这是我的代码。 每个连接都使用fork()创建新的子进程。每个连接都在新进程中运行。 但是如何制作我上面说过的动态池呢?
请帮助,这非常重要! 这是我应该做的最后一件事。

服务器代码:

int main(int argc, char * argv[])
{
        int cfd;
        int listener = socket(AF_INET, SOCK_STREAM, 0); //create listiner 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);
        }

        return 0;
}

这是一个设计或架构问题,对于代码的明确答案而言过于宽泛。

因此,您知道您希望在自己的进程中为每个新连接提供服务。 你的另外两个限制(至少)有两个问题:

首先,如何将新连接路由到已经运行的N个工作者之一?

这相对容易。 这里最常见的设计是:

  • 每个worker 继承侦听套接字并执行自己的accept()
    工作人员可能会互相监听套接字,因此只有一个人可以在任何给定时间调用accept(),或者他们每个人都可以调用accept() - 但在这种情况下要注意雷鸣般的群体
  • 工作人员通过UNIX文件描述符传递接收来自其他进程的接受()连接。
    例如,请参阅此SO问题

其次,我们如何确保N - K闲置工人流程可用?

这是一个更大的问题,你必须根据自己的舒适度和任何其他限制来回答这个问题。

您需要知道,不仅仅有多少工人还活着,而是哪些工人闲置(“免费”)。 让父母进程跟踪其子女是一个明显的开始,但这并不能区分闲置工人和忙碌工人。 您可以使用共享的互斥状态表,文件还是共享内存? 或者也许每个孩子通过socketpair()(与文件描述符传递相同)将其状态传递给父级?

那么,如果由于某种原因你超过K ,你如何安全地杀死一个闲散的工人呢? 信号? 在同一个socketpair()上给出的命令? 新闲工作者是否可以检查状态表是否自动终止,如果闲置将超过K 你如何从意外的工人终止中恢复(例如,SEGV)? 等等。

Apache的MPM prefork模块在这个问题空间中实现了一种可能的设计。 您可能想咨询它的想法。

您的代码似乎不满足条件号2.您的进程池未预先运行。 接受连接时会创建进程。 一种解释是你会做一堆分叉,然后让分叉的进程等待接受。 一个人会得到它,然后它会进行处理。

父进程需要跟踪有多少孩子。 你可以在一个等待的线程中执行此操作。 这将等待孩子死亡。 (请参阅man 2等待各种口味。)当进程数量变得太大时,您可以发送一个孩子可以捕获的信号以便正确终止。 但是,我假设父进程不会分叉更多的子进程,直到其中一些人死亡并且不会超额认购'K'限制。

暂无
暂无

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

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