我正在使用共享内存在两个进程之间进行通信。我使用char **附加到共享地址空间。问题是当我在生产者上填充数据然后将消费者附加到地址空间时,没有数据被传输。我只是得到空值
这是我的制片人的片段
// create shared memory
shm_handle = shmget(key, BUFF_SIZE * PAGE_SIZE, IPC_CREAT | 0644);
printf("\nhandle is %d\n", shm_handle);
// valid handle?
if (shm_handle == -1) {
printf("shared memory creation failed\n");
exit(0);
}
// attach to shared block, see man pages for detail
buf = (char**) shmat(shm_handle, 0, 0);
if (buf == (char **) -1) {
printf("Shared memory attach failed");
exit(0);
}
int a = 0;
buf = malloc(sizeof(char*) * BUFF_SIZE);
for (a = 0; a < BUFF_SIZE; a++) {
buf[a] = malloc(sizeof(char) * PAGE_SIZE);
}
和消费者
// create shared memory
shm_handle = shmget(key, BUFF_SIZE * PAGE_SIZE, IPC_CREAT | 0644);
printf("handle is %d", shm_handle);
// valid handle?
if (shm_handle == -1) {
printf("shared memory creation failed\n");
exit(0);
}
char ** buft;
int a = 0;
// attach to shared block
buf = (char**) shmat(shm_handle, 0, 0);
if (buf == (char **) -1) {
printf("Shared memory attach failed");
exit(0);
}
buf = malloc(sizeof(char*) * BUFF_SIZE);
buft = malloc(sizeof(char*) * PAGE_SIZE);
for (a = 0; a < BUFF_SIZE; a++) {
buf[a] = malloc(sizeof(char) * PAGE_SIZE);
buft[a] = malloc(sizeof(char) * PAGE_SIZE);
}
printf("%s", buf[0]);
答案 0 :(得分:1)
您的代码不会将您的字符串放在共享内存中。正如malloc
总是这样,它将它们放在堆上,因为你正在做:
buf = (char**) shmat(shm_handle, 0, 0);
...
/* now throw away the value of `buf` you got from shm */
buf = malloc(sizeof(char*) * BUFF_SIZE);
您需要做的是:
不使用堆在共享内存中分配您想要的东西
相反,为所有内容获取足够大量的共享内存,然后将其复制,逐个条目 - 即手动将其存储在内存中。
答案 1 :(得分:1)
在共享内存中分配内容非常棘手且容易出错,因为共享内存的地址在每个进程中都不一定相同。除非您采取措施确保地址相同,否则您无法将指针存储在共享内存中,因为它们不会指向正确的位置 - 您需要将偏移存储到共享内存中。 / p>
一旦从shmat
获得大量内存,您需要自己管理该空间内的分配,跟踪正在使用的内容和免费内容。在一般情况下,您需要使用共享空间重新实现malloc / free,因为系统malloc / free始终使用非共享堆内存。这不重要。
如果你只想要一些管理它的工作代码,你可以查看here,但这不是一个简单的问题。