0

Unix システムで C 言語でクライアント サーバー (TCP) プログラムを作成しています。クライアントが何らかの情報を送信し、サーバーが応答します。子プロセスごとに 1 つの接続しかありません。新しい接続はプールから事前実行中のプロセスを使用し、プールのサイズは動的であるため、空きプロセス (クライアントにサービスを提供していないプロセス) の数が減りすぎた場合は新しいプロセスを作成し、同様に増えすぎた場合は追加のプロセスを作成する必要があります。プロセスを終了する必要があります。

これは私のサーバーコードです。すべての接続は、 を使用して新しい子プロセスを作成し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);

}

4

1 に答える 1

1

同じリッスン ソケットで複数のプロセスがブロックされている場合accept、入ってくる新しい接続はそれらの 1 つに配信されます。(場合によっては、複数が起動する場合がありますが、実際に接続できるのは 1 つだけです)。したがって、 の後で複数の子を fork する必要がありますがlisten、 の前にaccept. acceptリクエストを処理した後、子は代わりに に戻りexitます。それは(1)と(2)を処理します。

(3) 難しいです。何らかの形の IPC が必要です。通常、適切な数の子を持つことだけを管理する親プロセスがあります。子プロセスは、IPC を使用して親プロセスがどれだけビジーかを伝える必要があります。次に、親はさらに多くの子をフォークするか (accept上記のループに入る)、子に信号を送信して、終了して終了するように指示します。またwait、子供の処理、予期しない死亡などの処理も​​行う必要があります。

使用する IPC は、おそらく共有メモリです。2 つのオプションは、SysV ( shmget) and POSIX (shm_open`) 共有メモリです。可能であれば、おそらく後者が必要です。アクセスの同期 (POSIX と SysV の両方がこれを支援するためのセマフォを提供しますが、ここでも POSIX を優先します) を処理するか、アトミック アクセスのみを使用する必要があります。

(実際には、X を超える空きの子が存在する瞬間にプロセスを終了させたくないでしょう。これは、それらを繰り返し取得して生成することにつながります。これはコストがかかります。最後の 1 秒...そのため、データは使用中/空きのビットマップよりも複雑です。)

このように動作するデーモンはたくさんあるので、コード例を簡単に見つけることができます。もちろん、Apache を見てみると、おそらくより複雑で、優れたパフォーマンスを得てどこにでも移植できることがわかるでしょう。

于 2013-04-29T18:58:41.800 に答える