1

server.cプログラムがゾンビプロセスを処理できるようにしようとしています。もともと、私はlinuxhowtos.org/C_C++/socketsignal(SIGCHLD,SIG_IGN);からその行を見つけました。これは魅力のように機能します。クライアントに接続してからクライアントを閉じることができますが、それでもすべてがスムーズに実行されます。

しかし、記事に書かれているようにSIG_IGNをSigCatcherに置き換えようとしていますが、クライアントが閉じられるとサーバープログラムが停止し始めます(「2」を無限に受信し続け、それを出力します)。

私は両方を試しwait3(NULL,WNOHANG,NULL)ましwait(-1)たが、どちらも問題を解決しませんでした。私はここで正確に何をしようとすべきですか?

void *SignalCatcher(int n)
{
  wait3(NULL,WNOHANG,NULL);
}

これは私のメインがどのように見えるかです:

   //signal(SIGCHLD, SIG_IGN);
   signal(SIGCHLD, SignalCatcher);

   for(;;)
   {
      clilen=sizeof(cliaddr);
      connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);


      if ((childpid = fork()) == 0)
      {
         close (listenfd);

         for(;;)
         {
            n = recvfrom(connfd,mesg,1000,0,(struct sockaddr*)&cliaddr,&clilen);
            write(connfd , "" , 1);
            mesg[n] = 0;
            printf("Received the following:\n");
            printf("%s",mesg);

         }

      }
      close(connfd);
   }
4

2 に答える 2

1
void *SignalCatcher(int n)
{
  wait3(NULL,WNOHANG,NULL);
}

する必要があります:

void SignalCatcher(int signum)
{
  wait3(NULL,WNOHANG,NULL);
}

シグナルハンドラでは、リターンタイプが非常に重要です(呼び出し規約が通常の関数呼び出しとは異なるため)。いずれにせよ、コンパイラは少なくとも警告を発しているはずです。

2番目:ループでは、recvfrom()からのエラーリターンを処理する必要があります。(そして書く() )

for(;;) {
        n = recvfrom(connfd,mesg,1000,0,(struct sockaddr*)&cliaddr,&clilen);
        if (n == -1 && errno = EAGAIN) continue;
        else if (n == 0) break; // for non-blocking sockets...
        write(connfd , "" , 1);
        mesg[n] = 0;
        printf("Received the following: %s\n", mesg);
     }
于 2013-02-27T22:23:01.670 に答える
0

どうしてそんなに一生懸命働くの?開始したらすぐに子をデーモン化します(たとえば、最初の子がすぐに終了し、孫がpid 1を親として続行するときに、2回フォークします)。ワーカープロセスの親であり続ける理由がない限り、これは物事を大幅に簡素化します。

于 2013-02-27T13:32:05.560 に答える