2つのプロセス間の通信を試みています。データ(名前、電話番号、住所など)を1つのプロセスで共有メモリに保存し、そのデータを他のプロセスで印刷しようとしています。
process1.c
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
int main ()
{
int segment_id;
char* shared_memory[3];
int segment_size;
key_t shm_key;
int i=0;
const int shared_segment_size = 0x6400;
/* Allocate a shared memory segment. */
segment_id = shmget (shm_key, shared_segment_size,
IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
/* Attach the shared memory segment. */
shared_memory[3] = (char*) shmat (segment_id, 0, 0);
printf ("shared memory attached at address %p\n", shared_memory);
/* Write a string to the shared memory segment. */
sprintf(shared_memory[i], "maddy \n");
sprintf(shared_memory[i+1], "73453916\n");
sprintf(shared_memory[i+2], "america\n");
/*calling the other process*/
system("./process2");
/* Detach the shared memory segment. */
shmdt (shared_memory);
/* Deallocate the shared memory segment.*/
shmctl (segment_id, IPC_RMID, 0);
return 0;
}
process2.c
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
int main ()
{
int segment_id;
char* shared_memory[3];
int segment_size;
int i=0;
key_t shm_key;
const int shared_segment_size = 0x6400;
/* Allocate a shared memory segment. */
segment_id = shmget (shm_key, shared_segment_size,
S_IRUSR | S_IWUSR);
/* Attach the shared memory segment. */
shared_memory[3] = (char*) shmat (segment_id, 0, 0);
printf ("shared memory22 attached at address %p\n", shared_memory);
printf ("name=%s\n", shared_memory[i]);
printf ("%s\n", shared_memory[i+1]);
printf ("%s\n", shared_memory[i+2]);
/* Detach the shared memory segment. */
shmdt (shared_memory);
return 0;
}
しかし、希望する出力が得られません。私が得た出力は次のとおりです:
shared memory attached at address 0x7fff0fd2d460
Segmentation fault
誰でも私を助けてください。これはshared_memory[3]
を初期化する正しい方法ですか?.
ありがとうございました。
char* shared_memory[3];
...
shared_memory[3] = (char*) shmat (segment_id, 0, 0);
shared_memory
をcharへの3つのポインタを保持できる配列として宣言しますが、実際に行うのは、配列の最後の1か所後ろにポインタを書き込むことです。他に何のためにメモリが使用されているのかわからないため、次に何が起こるかは通常予測できません。
shared_memory[0]
からshared_memory[2]
までのポインターを使用しようとすると、これらのポインターが初期化されたことがないため、状況は最終的に悪くなります。それらはスタックからの無意味なゴミで満たされています-したがって、セグメンテーション違反です。
一般に、配列とその要素を区別できていないようです。共有メモリIPCを試す前に、シーケンシャルコードの配列とポインタをたくさん使いやすくしてください。
共有メモリは、IPCそこから外すのが最も簡単で間違っている方法の1つであることに注意してください。効率の制約が厳しくなく、交換する場合たくさんのデータ、パイプ、名前付きパイプ、またはソケットを操作する方がはるかに簡単です。
他の2つの答えは何が悪いのかを教えてくれましたが、実行可能なコードを提供したいと思います。何でも渡すように変更できます。原則として、反対側に渡したすべての要素の長さを保存する必要があります。
//write.c
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/stat.h>
int main ()
{
key_t shm_key = 6166529;
const int shm_size = 1024;
int shm_id;
char* shmaddr, *ptr;
int next[2];
printf ("writer started.\n");
/* Allocate a shared memory segment. */
shm_id = shmget (shm_key, shm_size, IPC_CREAT | S_IRUSR | S_IWUSR);
/* Attach the shared memory segment. */
shmaddr = (char*) shmat (shm_id, 0, 0);
printf ("shared memory attached at address %p\n", shmaddr);
/* Start to write data. */
ptr = shmaddr + sizeof (next);
next[0] = sprintf (ptr, "mandy") + 1;
ptr += next[0];
next[1] = sprintf (ptr, "73453916") + 1;
ptr += next[1];
sprintf (ptr, "amarica");
memcpy(shmaddr, &next, sizeof (next));
printf ("writer ended.\n");
/*calling the other process*/
system("./read");
/* Detach the shared memory segment. */
shmdt (shmaddr);
/* Deallocate the shared memory segment.*/
shmctl (shm_id, IPC_RMID, 0);
return 0;
}
//read.c
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
int main ()
{
key_t shm_key = 6166529;
const int shm_size = 1024;
int shm_id;
char* shmaddr, *ptr;
char* shared_memory[3];
int *p;
/* Allocate a shared memory segment. */
shm_id = shmget (shm_key, shm_size, IPC_CREAT | S_IRUSR | S_IWUSR);
/* Attach the shared memory segment. */
shmaddr = (char*) shmat (shm_id, 0, 0);
printf ("shared memory attached at address %p\n", shmaddr);
/* Start to read data. */
p = (int *)shmaddr;
ptr = shmaddr + sizeof (int) * 2;
shared_memory[0] = ptr;
ptr += *p++;
shared_memory[1] = ptr;
ptr += *p;
shared_memory[2] = ptr;
printf ("0=%s\n", shared_memory[0]);
printf ("1=%s\n", shared_memory[1]);
printf ("2=%s\n", shared_memory[2]);
/* Detach the shared memory segment. */
shmdt (shmaddr);
return 0;
}
//実行の結果:
> [Lex:shm]$ ./write
> writer started.
> shared memory attached at address 0x7fa20103b000
> writer ended.
> shared memory attached at address0x7fd85e2eb000
> 0=mandy
> 1=73453916
> 2=amarica
dataを交換するのに十分な共有メモリを予約する必要があります。プロセスは、共有ポインターを使用していても、お互いのメモリにアクセスすることは想定されていません。実行時に書き込む生データのみが共有され、型チェックやその他のメタデータが渡されないことに注意してください。データで固定サイズの配列を使用できる場合は、共通の構造を使用して、データに簡単にアクセスできます。それ以外の場合は、プロセス間でデータを手動でマーシャリングする必要があります。