3

名前付きパイプを使用してプロセス間で構造体を渡そうとしています。パイプの非ブロッキングモードを開こうとして立ち往生しました。これがFIFOに書き込むための私のコードです:

void writeUpdate() {
    // Create fifo for writing updates:
    strcpy(fifo_write, routing_table->routerName);
    // Check if fifo exists:
    if(access(fifo_write, F_OK) == -1 )
        fd_write = mkfifo(fifo_write, 0777);
    else if(access(fifo_write, F_OK) == 0) {
        printf("writeUpdate: FIFO %s already exists\n", fifo_write);
        //fd_write = open(fifo_write, O_WRONLY|O_NONBLOCK);
    }
    fd_write = open(fifo_write, O_WRONLY|O_NONBLOCK);
    if(fd_write < 0)
        perror("Create fifo error");
    else {
        int num_bytes = write(fd_write, routing_table, sizeof(routing_table));
        if(num_bytes == 0)
            printf("Nothing was written to FIFO %s\n", fifo_write);
        printf("Wrote %d bytes. Sizeof struct: %d\n", num_bytes,sizeof(routing_table)+1);
        }
    close(fd_write);
   }

routing_tableは私の構造体へのポインタであり、割り当てられているので、そのようなfifoまたはsmthの名前のprobはありません。O_NONBLOCKオプションを指定せずにFIFOを開くと、初めてsmthが書き込まれますが、構造体の読み取りにも問題があるため、ブロックされます。そして、最初の後に、最初のFIFOが作成されますが、「。」、「..」という名前の他のFIFOが表示されます。O_NONBLOCKオプションを設定すると、FIFOが作成されますが、常にエラーがスローされます:'そのようなデバイスまたはアドレスはありません'。なぜこれが起こるのか考えていますか?ありがとう。

編集:わかりました。これで、FIFOを開くことについては明確になりましたが、別の問題があります。実際、FIFOへの構造体の読み取り/書き込みが最初の問題でした。構造体を読み取るための私のコード:

void readUpdate() {
struct rttable *updateData;
allocate();

strcpy(fifo_read, routing_table->table[0].router);

// Check if fifo exists:
if(access(fifo_read, F_OK) == -1 )
    fd_read = mkfifo(fifo_read, 777);
else if(access(fifo_read, F_OK) == 0) {
    printf("ReadUpdate: FIFO %s already exists\n Reading from %s\n", fifo_read, fifo_read);        
}
fd_read = open(fifo_read, O_RDONLY|O_NONBLOCK);
int num_bytes = read(fd_read, updateData, sizeof(updateData));
close(fd_read);
if(num_bytes > 0) {
    if(updateData == NULL)
        printf("Read data is null: yes");
    else
        printf("Read from fifo: %s %d\n", updateData->routerName, num_bytes);

    int result = unlink(fifo_read);
    if(result < 0)
        perror("Unlink fifo error\n");
    else {
        printf("Unlinking successful for fifo %s\n", fifo_read);
        printf("Updating table..\n");
        //update(updateData);
        print_table_update(updateData);
    }
} else
    printf("Nothing was read from FIFO %s\n", fifo_read);
}

これはFIFOを開いて読み込もうとしますが、FIFOには何も入っていないようですが、writeUpdateでは最初に4バイトを書き込んだと表示されます(これも間違っているようです)。読み取り時に、最初は'a'を出力し、その後num_bytesは常に<=0になります。私は周りを見回して、単純な書き込み/読み取りでこの例を見つけただけですが、構造体を書くときにもっと必要なものはありますか?

私の構造は次のようになります:

typedef struct distance_table {
char dest[20];       //destination network
char router[20];     // via router..
int distance;
} distance_table;

typedef struct rttable {
char routerName[10];
char networkName[20];
struct distance_table table[50];
int nrRouters;
} rttable;

struct rttable *routing_table;
4

1 に答える 1

3

「そのようなデバイスまたはアドレスはありません」はENXIOエラーメッセージです。マニュアルページを見るopenと、特に次の場合にこのエラーが報告されていることがわかります。

O_NONBLOCK | O_WRONLYが設定され、指定されたファイルはFIFOであり、読み取り用にファイルを開いているプロセスはありません。(...)

これはまさにあなたの状況です。したがって、表示されている動作は正常です。リーダーのないパイプに(ブロックせずに)書き込むことはできません。読み取り用のパイプに何も接続されていない場合、カーネルはメッセージをバッファリングしません。

したがって、必ず「プロデューサー」の前に「コンシューマー」を開始するか、プロデューサーの非ブロックオプションを削除してください。

ところで:使用accessとは、ほとんどの場合、チェックの時間から使用の時間の問題に自分自身を開放することです。使用しないでください。試してみてくださいmkfifo-それがうまくいくなら、あなたは良いです。で失敗した場合はEEXISTS、あなたも元気です。それ以外の方法で失敗した場合は、クリーンアップして救済します。

質問の2番目の部分では、送信しようとしているデータがどの程度正確に構造化されているかに完全に依存します。Cでランダム構造体をシリアル化することは、特に変数データ(たとえば、sなど)が含まれている場合は、まったく簡単ではありませんchar *

構造体にプリミティブ型のみが含まれ(ポインターは含まれず)、両側が同じマシン上にある(そして同じコンパイラーでコンパイルされている)場合、構造体全体の一方と他方でwriterawが機能するはずです。read

たとえば、より複雑なデータ型のC-シリアル化手法を見ることができます。

あなたの特定の例に関して:あなたはあなたの構造体へのポインタと単純な構造体の間で混乱しています。

書き込み側では、次のようになります。

int num_bytes = write(fd_write, routing_table, sizeof(routing_table));

routing_tableはポインタなので、これは正しくありません。必要なもの:

int num_bytes = write(fd_write, routing_table, sizeof(*routing_table));
// or sizeof(struct rttable)

読み取り側でも同じです。updateData受信サイズについても、私が知る限り、あなたは割り当てていません。あなたもそれをする必要があります(でmalloc、そしてそれを解放することを忘れないでください)。

struct rttable *updateData = malloc(sizeof(struct rrtable));
于 2011-05-21T09:14:00.020 に答える