I am trying to communicate between two processes. I am trying to save data(like name, phone number, address) to shared memory in one process and trying to print that data through other process.
我试图在两个进程之间进行通信。我试图在一个进程中将数据(如姓名,电话号码,地址)保存到共享内存,并尝试通过其他进程打印该数据。
process1.c
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
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;
}
But I am not getting the desired output. the output which i got is:
但我没有得到理想的输出。我得到的输出是:
shared memory attached at address 0x7fff0fd2d460
Segmentation fault
Anyone can please help me with this. Is this the correct way of initializing shared_memory[3]
.
任何人都可以帮助我。这是初始化shared_memory的正确方法[3]。
Thank you.
谢谢。
3 个解决方案
#1
15
char* shared_memory[3];
...
shared_memory[3] = (char*) shmat (segment_id, 0, 0);
You declare shared_memory
as an array capable of holding three pointers to char, but what you actually do with it is to write a pointer one place behind the end of the array. Since there is no telling what the memory there is otherwise used for, what happens next is generally unpredictable.
你将shared_memory声明为一个能够保存三个指向char的指针的数组,但实际上你要做的就是在数组末尾后面写一个指针。由于无法确定其他用途的内存,接下来发生的事情通常是不可预测的。
Things go conclusively bad afterwards when you try to make use of the pointers in shared_memory[0]
through shared_memory[2]
, because those pointers have never been initialized. They are filled with meaningless garbage from the stack -- thus the segmentation fault.
当你试图利用shared_memory [0]到shared_memory [2]中的指针时事情变得非常糟糕,因为那些指针从未被初始化。它们充满了堆栈中无意义的垃圾 - 因此是分段错误。
It seems, in general, that you're failing to distinguish between the array and its elements. You should go and make yourself a lot more comfortable with arrays and pointers in sequential code before you try your hand at shared-memory IPC.
一般来说,您似乎无法区分数组及其元素。在尝试使用共享内存IPC之前,您应该使用顺序代码中的数组和指针让自己更舒服。
Note that shared memory is one of the more easy-to-get-wrong ways of doing IPC out there. Unless you have rigid efficiency constraints and are going to exchange a lot of data, it's much easier to work with pipes, named pipes, or sockets.
请注意,共享内存是在那里进行IPC更容易弄错的方法之一。除非您有严格的效率约束并且要交换大量数据,否则使用管道,命名管道或套接字会更容易。
#2
12
The other two answers told you what's wrong, but I want to give you a runnable code. You can modify it to pass anything, the principle is you need to save the length of every element you passed to the other side.
另外两个答案告诉你什么是错的,但我想给你一个可运行的代码。您可以修改它以传递任何内容,原则是您需要保存传递给另一方的每个元素的长度。
//write.c
//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
//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;
}
//Result of run:
//运行结果:
> [lex:shm]$ ./write
> writer started.
> shared memory attached at address 0x7fa20103b000
> writer ended.
> shared memory attached at address0x7fd85e2eb000
> 0=mandy
> 1=73453916
> 2=amarica
#3
0
You should be reserving enough shared memory to exchange the data. Processes aren't supposed to access each others memory, even if using shared pointers. Keep in mind only the raw data you write during runtime is shared, there's no type checking or any other metadata passed. You can use a common structure, if your data allows it using fixed-size arrays, to access the data more easily. Otherwise, you'll have to manually marshal the data between the processes.
您应该保留足够的共享内存来交换数据。即使使用共享指针,进程也不应该访问彼此的内存。请记住,只有在运行时编写的原始数据才会被共享,没有类型检查或传递任何其他元数据。如果数据允许使用固定大小的数组,则可以使用通用结构来更轻松地访问数据。否则,您必须手动封送进程之间的数据。
#1
15
char* shared_memory[3];
...
shared_memory[3] = (char*) shmat (segment_id, 0, 0);
You declare shared_memory
as an array capable of holding three pointers to char, but what you actually do with it is to write a pointer one place behind the end of the array. Since there is no telling what the memory there is otherwise used for, what happens next is generally unpredictable.
你将shared_memory声明为一个能够保存三个指向char的指针的数组,但实际上你要做的就是在数组末尾后面写一个指针。由于无法确定其他用途的内存,接下来发生的事情通常是不可预测的。
Things go conclusively bad afterwards when you try to make use of the pointers in shared_memory[0]
through shared_memory[2]
, because those pointers have never been initialized. They are filled with meaningless garbage from the stack -- thus the segmentation fault.
当你试图利用shared_memory [0]到shared_memory [2]中的指针时事情变得非常糟糕,因为那些指针从未被初始化。它们充满了堆栈中无意义的垃圾 - 因此是分段错误。
It seems, in general, that you're failing to distinguish between the array and its elements. You should go and make yourself a lot more comfortable with arrays and pointers in sequential code before you try your hand at shared-memory IPC.
一般来说,您似乎无法区分数组及其元素。在尝试使用共享内存IPC之前,您应该使用顺序代码中的数组和指针让自己更舒服。
Note that shared memory is one of the more easy-to-get-wrong ways of doing IPC out there. Unless you have rigid efficiency constraints and are going to exchange a lot of data, it's much easier to work with pipes, named pipes, or sockets.
请注意,共享内存是在那里进行IPC更容易弄错的方法之一。除非您有严格的效率约束并且要交换大量数据,否则使用管道,命名管道或套接字会更容易。
#2
12
The other two answers told you what's wrong, but I want to give you a runnable code. You can modify it to pass anything, the principle is you need to save the length of every element you passed to the other side.
另外两个答案告诉你什么是错的,但我想给你一个可运行的代码。您可以修改它以传递任何内容,原则是您需要保存传递给另一方的每个元素的长度。
//write.c
//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
//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;
}
//Result of run:
//运行结果:
> [lex:shm]$ ./write
> writer started.
> shared memory attached at address 0x7fa20103b000
> writer ended.
> shared memory attached at address0x7fd85e2eb000
> 0=mandy
> 1=73453916
> 2=amarica
#3
0
You should be reserving enough shared memory to exchange the data. Processes aren't supposed to access each others memory, even if using shared pointers. Keep in mind only the raw data you write during runtime is shared, there's no type checking or any other metadata passed. You can use a common structure, if your data allows it using fixed-size arrays, to access the data more easily. Otherwise, you'll have to manually marshal the data between the processes.
您应该保留足够的共享内存来交换数据。即使使用共享指针,进程也不应该访问彼此的内存。请记住,只有在运行时编写的原始数据才会被共享,没有类型检查或传递任何其他元数据。如果数据允许使用固定大小的数组,则可以使用通用结构来更轻松地访问数据。否则,您必须手动封送进程之间的数据。