0

共有メモリをパイプとして使用しようとしていますが、いくつかの問題が発生します。

  1. セグメントを削除できません
  2. メイン関数は終了しません。return 0

    int main()
    {
      int spd[2], pid, rb;
      char buff[4096];
      if (shm_pipe_pipe(spd) < 0)
      {
            perror("shm_pipe_pipe");
            exit(1);
      }
      if (fork())
      {
            rb = shm_pipe_read(spd[0], buff, sizeof(buff));
            if (rb > 0)
                    write(1, buff, rb);
      }
      else
      {
             shm_pipe_write(spd[1], "hello world!\n", sizeof("hello world!\n"));
      }
    
      shm_pipe_close(spd[0]);
      shm_pipe_close(spd[1]);
      printf("end main\n");
      return 0;
    }
    

最後の出力は「end main」ですが、プログラムは閉じずにbashに戻りません...共有メモリ全体に関連していると確信しています:

shm_pipe_pipe()共有メモリ セグメントとポインタを共有メモリに割り当てます。

shmid = shmget(key, PIPE_SIZE, IPC_CREAT | IPC_EXCL | 0600);
buffer = (char*)shmat(pipes_array[i].m_shmid, NULL, 0)) == NULL)

shm_pipe_write and shm_pipe_read共有メモリとの間で memcpy() を実行するだけです

shm_pipe_close()free はセグメントへのポインターであり、セグメントを削除します。

shmdt(buffer);
shmctl(shmid, IPC_RMID, NULL);

なぜ機能しないのかわかりません。

shmdt の man ページには、fork(2) the child inherits the attached shared memory segments.

shmdtそのため、父と子で2回使用しようとしましたが、エラーが発生しました

Invalid argument

main()「end main」を印刷した後にスタックが発生した場合、で共有メモリのステータスを確認しようとするとipcs -m、それnattchが 1 であり、keyが 0 であることがわかります... I の後でのみctrl+c main()、メモリセグメントはから削除されますipcs -m

さらにどのような情報を提供すればよいかわかりません。私はすべての関数を書いたわけではありません。それはたくさんあり、問題ではないと思います...

4

2 に答える 2

1

私はあなたが何かについて混乱していると思います。

最後の出力は「end main」です

shm_pipe_close() は、セグメントへのポインタを解放し、セグメントを削除します

exitただし、子ブロックに no を指定して書かれているように、このコードは親と子の両方で実行する必要があります。

  shm_pipe_close(spd[0]);
  shm_pipe_close(spd[1]);
  printf("end main\n");

つまり、2 回 (子が で行き詰まっていない限り、shm_pipe_read以下を参照)。「セグメントの削除」が単一の共有メモリエンティティを参照している場合、これはおそらく意図的ではありません。

それを超えて、結果は、データが反対側で読み取られるか書き込まれるまで待機する、パイプでの通常のブロック読み取り/書き込み呼び出しのように機能shm_pipe_readするかどうかによって異なります。shm_pipe_writeあなたの書き込みは確かにそうではなく、おそらく読み取りもそうではないと思います。

これは、親で発生する可能性があることを意味しshm_pipe_write、「パイプ」(実際には共有メモリセグメント) がすぐに削除されます。これにより何かがshm_pipe_read停止する場合 (セグメントがなくなったため)、(ring0 がコメントで述べているように) 問題を説明している可能性があります。

于 2013-01-11T17:04:26.763 に答える
0

あなたの問題はここにあると思います:

 shmid = shmget(key, PIPE_SIZE, IPC_CREAT | IPC_EXCL | 0600);

権限を変更して、子と親の両方が共有メモリ セグメントにアクセスできるようにします。

 shmid = shmget(key, PIPE_SIZE, IPC_CREAT | IPC_EXCL | 0666);

私はあなたの機能が何をしているのか正確にはわからないので...ここに動作する同様のプログラムがあり、他の間違いがあるかどうかを参照できます(ところで-ここの権限を0600に変更し、メインプロセスを見ることができました完了しますが、子はハングします):

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main(int argc, char * argv[])
{
    key_t key = 1111;
    int shmid;
    char *buff;
    char *s;
    char *addr = NULL;

    if((shmid = shmget(key, 4096, IPC_CREAT | IPC_EXCL | 0666)) < 0 ) {
         perror("shmget");
        return -1;
    }
    if((buff = shmat(shmid, addr, 0)) == (char *)-1) {
        perror("shmat");
        return -1;
    }
    if(fork()){
      printf("I'm the child\n");
      while(strlen(buff) == 0) {}
      for(s = buff; *s != NULL; s++)
        putchar(*s);
      printf("\nChild is done\n");
    }
    else {
      printf("I'm the parent\n");
       strcpy(buff, "hello world!\0");
      printf("Parent is done.\n");
    }
    shmdt(addr);
    shmctl(shmid, IPC_RMID, NULL);
    return 0;
}
于 2013-01-11T17:54:55.490 に答える