如何使用共享内存在两个进程之间进行通信

我试图在两个进程之间进行通信。 我试图在一个进程中将数据(如姓名,电话号码,地址)保存到共享内存,并尝试通过其他进程打印该数据。

process1.c

#include  #include  #include  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  #include  #include  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]的正确方法shared_memory[3]

谢谢。

 char* shared_memory[3]; ... shared_memory[3] = (char*) shmat (segment_id, 0, 0); 

你将shared_memory声明为一个能够保存三个指向char的指针的数组,但实际上你要做的就是在数组末尾后面写一个指针。 由于无法确定其他用途的内存,接下来发生的事情通常是不可预测的。

当你试图利用shared_memory[0]shared_memory[2]中的指针时事情变得非常糟糕,因为那些指针从未被初始化。 它们充满了堆栈中无意义的垃圾 – 因此是分段错误。

一般来说,您似乎无法区分数组及其元素。 在尝试使用共享内存IPC之前,您应该使用顺序代码中的数组和指针让自己更舒服。

请注意,共享内存是在那里进行IPC更容易弄错的方法之一。 除非您有严格的效率约束并且要交换大量数据,否则使用管道,命名管道或套接字会更容易。

另外两个答案告诉你什么是错的,但我想给你一个可运行的代码。 您可以修改它以传递任何内容,原则是您需要保存传递​​给另一方的每个元素的长度。

//write.c

 #include  #include  #include  #include  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  #include  #include  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 

您应该保留足够的共享内存来交换数据 。 即使使用共享指针,进程也不应该访问彼此的内存。 请记住,只有在运行时编写的原始数据才会被共享,没有类型检查或传递任何其他元数据。 如果数据允许使用固定大小的数组,则可以使用通用结构来更轻松地访问数据。 否则,您必须手动封送进程之间的数据。