我正在尝试在两个进程之间进行通信。我试图在一个进程中将数据(如姓名,电话号码,地址)保存到共享内存,并尝试通过其他进程打印该数据。
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]
的正确方法。
谢谢。
答案 0 :(得分:16)
char* shared_memory[3];
...
shared_memory[3] = (char*) shmat (segment_id, 0, 0);
你将shared_memory
声明为一个能够容纳三个指向char的指针的数组,但你实际上用它来写一个指针在数组末尾后面的一个地方。由于无法确定其他用途的内存,接下来发生的事情通常是不可预测的。
当你试图利用shared_memory[0]
到shared_memory[2]
中的指针时事情变得非常糟糕,因为这些指针从未被初始化。它们充满了堆栈中无意义的垃圾 - 因此是分段错误。
一般来说,您似乎无法区分数组及其元素。在尝试使用共享内存IPC之前,你应该让自己很多更容易使用顺序代码中的数组和指针。
请注意,共享内存是在那里进行IPC更容易搞错的方法之一。除非您有严格的效率约束并且要交换很多数据,否则使用管道,命名管道或套接字会更容易。
答案 1 :(得分:13)
另外两个答案告诉你错误,但我想给你一个可运行的代码。您可以修改它以传递任何内容,原则是您需要保存传递给另一方的每个元素的长度。
//为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
答案 2 :(得分:0)
您应该保留足够的共享内存来交换数据。即使使用共享指针,进程也不应该访问彼此的内存。请记住,只有在运行时编写的原始数据才会被共享,没有类型检查或传递任何其他元数据。如果数据允许使用固定大小的数组,则可以使用通用结构来更轻松地访问数据。否则,您必须手动封送进程之间的数据。