2011-11-10 11 views
-2

助けてくれる人、または正しい方向に向ける人のために。Unix selectシステムコール

./mainprogram ./prog1 5 ./prog2 9 ./prog3 4 

これまでのところ、私はそれが最初のプログラムを読み込むために働いてきたが、私はそれが動作しない2つのプログラムを読み込むしようとすると:私は、他のプログラムで読み込むと、このようなコマンドライン引数は、プログラムを持っています。私は目の2番目のセットが助けるかもしれないと思った。ここで

#include <errno.h> 
#include <cstdio> 
#include <iostream> 
#include <sys/wait.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <sys/select.h> 
#define BUFSIZE 1024 
using namespace std; 

int main(int argc, char *argv[]) 
{ 
    char buf[BUFSIZE]; 
    int bytesread; 
    int checkfd[((argc-1)/2)]; 
    int ready; 
    int maxfd= 0; 
    int programs= ((argc-1)/2); 
    fd_set readset; 


    typedef int pipe_t[2]; 
    pipe_t *mypipes =(pipe_t*)calloc(programs,sizeof(pipe_t)); 

    for(int k=0; k<= programs;k++){ 
     pipe(mypipes[k]); 
     checkfd[k]=true; 
    } 

    for(int i=1; i<=argc-1; i+2){ 
     pid_t childpid =fork(); 

     //child code 
     if(childpid==0){ 

      dup2(mypipes[i][1],mypipes[i][1]); 
      //for(int q=0; q<= programs;q++){ 
      // close(mypipes[q][0]); 
      // close(mypipes[q][1]); 
      // } 

      int a=execl(argv[i],argv[i],(char*)argv[i+1],(char *)NULL); 
      if(a==-1){ 
       perror("The following error occurred at a"); 
       exit(1); 

      } 
     } 
     //parent code 
     else{ 

      int result; 
      dup2(mypipes[i][0],mypipes[i][0]); 

      for(int z=0; z<programs; z++){ 

       FD_ZERO(&readset); 

       if(checkfd[z]){ 
        FD_SET(mypipes[z][0],&readset); 
        if(mypipes[z][0] >= maxfd){ 
         maxfd= mypipes[z][0]+1; 
        } 

       } 
       else{ 
        continue; 
       } 

       ready=select(maxfd,&readset,NULL,NULL,NULL); 

       if((ready==-1) && (errno== EINTR)){ 
        continue; 
       } 
       else if(ready== -1){ 
        break; 
       } 


       for(int k=0; k<programs; k++){ 

        if(FD_ISSET(mypipes[k][0], &readset)){ 

         bytesread= read(mypipes[k][0], buf, BUFSIZE); 

         if(bytesread < 0){ 

          close(mypipes[k][0]); 

         } 
        } 
       } 
      } 
     } 
    } 

    for(int q=0; q<= programs;q++){ 
     close(mypipes[q][0]); 
     close(mypipes[q][1]); 
     wait(NULL); 
    } 

    return 0; 

} 

は私が読んでいるプログラムの一つである:

#include <cstdlib> 
#include <iostream> 
#include <string.h> 
#include <stdio.h> 

using namespace std; 

int main(int argc, char** argv) 
{ 
    int cube(int); 
    void process(int(*)(int),int); 

    if (argc != 2){ 
     cerr << "Usage " << argv[0] << " number"; 
     return 1; 
    } 

    int n = atoi(argv[1]); 
    process(cube, n); 
    return 0; 
} 

int cube(int n){ 
    return n*n*n; 
} 
void process(int(*f)(int), int n){ 
    sleep(f(3) % 4); 
    for (int k = 1; k <= n; k++){ 
     int result = f(k); 
     char buffer[1024]; 
     sprintf(buffer, "cube: %d\n", result); 
     write(1,buffer, strlen(buffer)); 
     //write(1, &result, sizeof(int)); 
     // cout<<result<<endl; 
     sleep(rand() %3); 
    } 
} 

残りだけ異なる配列と同じ構造です。問題は、2つのプログラムを渡すときに最初に出力されるシーケンスを出力し、2番目、3番目などの出力が出力されないことです。

+2

さらに最小限の例までデバッグすることはできますか?また、コードの書式をきれいにして、読んでも苦労しないようにすることはできますか? – ObscureRobot

+0

-1。 「うまくいきません」は有効な問題の説明ではありません。また、「ローカライズすぎる」と投票した。 –

+0

質問は正確には何ですか?あなたはhttp://linux.die.net/man/2/select_tut –

答えて

1

コメントのカップル:

  • dup2(mypipes[i][1],mypipes[i][1]);はNOOPです - あなたはdup2(mypipes[i][1],1);
  • をしたいすべてのプロセスは、彼らが使用していないすべてのFDSを閉じる必要があります。各パイプの各端は、1つのプロセス内で1つのfdだけ開いた状態になり、他のすべてのプロセスは閉じた状態になります。したがって、各子には1つのパイプの書き込み終了があり、親にはパイプの読み込み終了と書き込み終了がなくてはならず、すべての冗長FDが閉じられるべきです。 FD_CLOEXECを使うと、これをもっと簡単にすることができます.fd 1を除くすべてのfdがCLOEXECの場合、execの後に子プロセスがクリーンになります。
  • あなたのセレクトループがセットアップループの内側にあるように見えるので、最初の子が始まったときに選択を開始し、最後の子を起動した後に選択を止めます。前者は無害で、後者は問題です。おそらく、1つのループで子をセットアップし(foringとexecing)、完全に別のwhile(1)ループ呼び出しを選択します。
+0

あなたの役に立つ回答に感謝します。私はあなたの提案を試し、それが私を得る場所を見ていきます – user975044

0

あなたは子プロセスのためのstdoutを交換する代わりにdup2(mypipes[i][1],mypipes[i][1]);dup2(mypipes[i][1], 1);を行うことを意味するものではありませんでしたか?

関連する問題