2017-10-19 6 views
0

これは私と一緒にクリックしていないトピックの宿題なので、もっと詳しく解説されている説明を読んでいただければ幸いです。私の共有メモリの名前をパイプに書き込むことができません

私は、共有メモリの名前を指定してアクセスできるように、他の複数のプロセス用に共有メモリを作成しようとしています。私の他のプロセスはパイプを介して親プロセスに接続されています。パイプの作成後に共有メモリの名前をパイプに書きたいと思います。ここまでは私のコードです。私はprintステートメントには決してできません。

書き込みをコメントアウトすると、プログラムは1回動作します。しかし、プログラムをもう一度実行しようとすると、名前空間の名前を変更して機能させる必要があります。私はなぜそれが起こっているのか分かりません。私は理解していないこれらの機能の1つの特性があると確信しています。

int shm; 
    char *p; 
    shm = shm_open("Name", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); 
    size_t len = 4 * 255; 

    if (ftruncate(shm, len) == -1) { 
    perror("Truncate"); 
    return 1; 
    } 

    p = mmap(0, 4, PROT_WRITE, MAP_SHARED, shm, 0); 
    if (p == MAP_FAILED){ 
    perror("mmap"); 
    return 1; 
    } 

    write(fd[1], "Name", 30); 

    printf("Initiator: Shared memory for Consonanats is %d.\n", shm); 
+0

オープンされているリソースは、終了すると終了する必要があります。共有メモリを 'shm_close'する必要があります。これにより、プログラムを再実行するたびに名前空間を変更する必要がなくなります。 – Hypino

+0

共有メモリセグメントの名前は、スラッシュ( '/')で始まる必要があります。 –

+0

@Hypino、 "shm_unlink'のスペルが間違っているようです。 'shm_open()'の標準的なものではなく、少なくともshm_close()はありません。 –

答えて

0

あなたwrite()呼び出しの引数は矛盾しています:

write(fd[1], "Name", 30); 

あなたは明らか配列の境界をオーバーラン5バイト配列の30のバイトを書き込もうとしています。

また、write()コールの戻り値もチェックしていません。原則として、短い書き込みが発生する可能性があるため、バイトの残りの部分を転送するために1回以上の追加呼び出しを行う必要があります。おそらくもっと可能性がありますが、書き込みが完全に失敗する可能性があります。その場合は、おそらく注意を払い、何かをしたいと思うかもしれません。どちらの条件も、write()の戻り値を介して通知されます。

はまた、あなたが書いた:私は再度プログラムを実行しようとすると、

を、私はそれを動作させるための私の 名前空間の名前を変更する必要があります。私はなぜそれが起こっているのか分かりません。 私は を理解していないこれらの機能のいずれかのプロパティがあると確信しています。

はい、確かに理解できないプロパティがあります。共有メモリセグメントには、カーネルスコープと永続性があります。とりわけ、生涯はそれらを生み出すプロセスの生涯に限定されず、その名前はシステムにとってグローバルであることを意味する。そのため、同じ名前を指定することによって、異なるプロセスが同じセグメントにアクセスできるようになります。

@Hypinoがコメントで見たように、作成したセグメントを削除することはありません。実際、あなたはそれを直接行うことはできません。代わりに、は、shm_unlink()でリンク解除する必要があります。セグメントの名前はカーネルから分離されますが、それを直接破壊するわけではありません。他のプロセス(または同じプロセスさえも)がまだそれを使用している可能性があるので、安全ではありません。リンクが解除された後、セグメントはティアダウンと削除の準備が整いますが、プロセスがマッピングされなくなった後にのみ発生します。その間、指定された名前の異なるセグメントを作成することができます。

したがって、共有メモリセグメントは、安全かつ実用的になるとすぐにリンクを解除することが一般的です。実際には、それをマップする必要があるすべてのプロセス(名前で)が実行した後、できるだけ早くそれを意味します。セグメントマッピングはプロセスごとのプロパティなので、プロセスが終了すると消えます。

実際には、名前を再利用すると問題が発生する理由は不明です。フラグの中にO_EXCLを指定しないかぎり、以前の実行から残された既存の共有メモリセグメントを開くことができます。私は、その特定の問題はあなたが省略したコードの何かを回転させると思う。

また、セグメント名に関して、名前の選択の自由が絶対ではないことに注意してください。 shm_open()のためのLinuxのマニュアルがそれを置くよう:携帯用として

を、共有メモリオブジェクトは、フォーム/somenameの 名前で識別されなければなりません。すなわち のスラッシュとそれに続く1つ以上の文字(スラッシュではない)の後に続く、NAME_MAX(つまり255)までのヌルで終了する文字列です。

+0

あなたは私の教授が講義全体でしたより3つの段落でもっと教えてくれました、ありがとう!大変感謝しています。 – user4493284

関連する問題