2016-03-26 12 views
0

完全に接続されたメッシュトポロジのモデルを作成します。私はパイプを使ってお互いに通信する親と子を持っています。したがって、各プロセスは複数のパイプからデータを読み取る必要があります。私はそれをどうやって行うのか分かりません。複数のパイプからデータを読み取る

各プロセスには、増分(0 - 親、1,2,3など)として "ローカルID"があります。

パイプの2次元配列を作成しました。最初の配列 - 目的地、第2のアレイ - 源:マルチキャストメッセージを送信するため

struct pipes_t 
{ 
    int rdwr[2]; 
}; 

struct dataIO_t 
{ 
    int processes; // number of processes 
    int8_t lid; // prosecc local id (0,1,2 etc) 
    struct pipes_t pipes[MAX_LOCAL_ID+1][MAX_LOCAL_ID+1]; 
}; 

機能:スレッドことなく、任意のプロセスから多くのパイプからデータを読み取る方法

int send(struct dataIO_t* data) { 
    for(int i = 0; i < data->processes; i++) 
     if(write(data->pipes[i][data->lid].rdwr[1], "Hello world\n", 12) != 1) 
      return 1; 
    return 0; 
} 

? 私は1つに接続するためにすべてのパイプを機能dup2を使用しようとしましたが、それは悪い考えた:

int receive(struct dataIO_t* data) { 
    int fd[2]; 
    pipe(fd); 

    const int BSIZE = 100; 
    ssize_t nbytes; 
    char buf[BSIZE]; 

    for(int i = 0; i < data->processes; i++) 
     if(i != data->lid) 
      if (dup2(data->pipes[data->lid][i].rdwr[0], fd[0]) == -1) 
       return 1; 

    nbytes = read(fd[0], buf, BSIZE); 
    printf("Msg (%d): %s\n", data->lid, buf); 

    return 0; 
} 

禁止事項:この演習では、私はpollselectと同じ機能を使用することはできません。

+0

あなたが探している機能は 'poll'です。それはいくつかのファイル記述子で待機し、読み込みまたは書き込みが可能なものを返します。古いものである 'select'ともう少し複雑な' epoll'もあります。 –

+0

@ColonelThirtyTwo質問を更新しましたが、この機能を使用することはできません。 –

+0

賢明なオプション(['select()'](http://pubs.opengroup.org/onlinepubs/9699919799/)を使用できない場合は、 functions/select.html)と ['poll()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html)と非標準の親戚)を作成する必要があります。読み込まれたファイル記述子non-blocking(['fcntl()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html)、 'F_GETFL'、' F_SETFL'、 'O_NONBLOCK')読み込み可能なデータがあるかどうかを調べるには、各ファイル記述子をループする必要があります。 –

答えて

3

あなたは発見しているかもしれませんがあなたが

など、選択、あなたはポールを使用せずに、複数のファイルディスクリプタから読みたいと言う、あなたは、単にいくつかのパイプの1から読み取ることができない、それが作品を願って、そこにあるかのためデータがなければブロックします。

これを解決するには、読み込みたいファイル記述子をすべてノンブロッキングと設定することができます。つまり、利用可能なデータがない場合はすぐに読み込みを返します。擬似コードで

for each fd in fds 
    mode = fcntl(fd, F_GETFL); 
    fcntl(fd, F_SETFL, mode | O_NONBLOCK) 

forever 
    for each fd in fds 
     if read(fd) 
      process data 
    sleep a little to avoid 100% CPU usage 
+0

'setsockopt()'はソケット記述子ではなくパイプ記述子で動作しますか? –

+0

@JonathanLeffler:良い点、私は擬似コードを更新しています。これは間違いなく動作します(擬似コードは間違いなく機能します)。 –

+0

ビジー待機の代わりに 'select'か' poll'を使うべきです。 – jch

関連する問題