在 Linux 上写入映射内存时返回带 mmap 的共享内存
Posted
技术标签:
【中文标题】在 Linux 上写入映射内存时返回带 mmap 的共享内存【英文标题】:Shared memory with mmap returns when writing to mapped memory on linux 【发布时间】:2012-10-16 14:03:39 【问题描述】:我试图找出共享内存,并尝试编写一个涉及消费者和生产者的简单程序。我没有进入消费者部分,发现了这个奇怪的小问题:父母将返回*spool=3;
,没有押韵或理由。 dmesg
上没有任何内容。
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define PRODUCER_ERROR(msg) \
do perror("Producer Error: " msg "\n"); exit(1); while(0)
#define SHM_NAME "/my_sharedmem"
void producer();
int main(int argc, char *argv[])
pid_t pID = fork();
if (pID == 0)
// Code only executed by child process
printf ("Son here\n");
return 0;
else if (pID < 0)
perror("Unable to fork\n");
exit(1);
else
// Code only executed by parent process
printf ("Parent here\n");
producer();
return 0;
return 0;
void producer()
int fd, d;
unsigned* spool;
printf("<<Producer>> started\n");
fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO ); // FIXED
printf ("<<Producer>> memory file opened\n");
spool = mmap(NULL, sizeof(unsigned), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, 0);
printf ("<<Producer>> mmaped to %p\n\tGonna write.\n", spool);
perror(NULL);
*spool = 3;
// msync(spool, sizeof(unsigned), MS_SYNC | MS_INVALIDATE);
printf("<<Producer>> ended\n");
编辑:固定 shm_open 模式参数
【问题讨论】:
【参考方案1】:您使用 shm_open 获得的对象大小为零。你需要为它分配一些空间。 mmap 将允许您映射超出其大小的事物(shm 对象和文件),但是当您访问该内存时会崩溃。
在 shm_open 之后这样的事情是你想要做的:
ftruncate(fd, <the size you want>);
您也可以在 mmap 之后执行此操作,如果它能让您的船浮起来的话。
【讨论】:
【参考方案2】:shm_open
的模式参数错误。这应该是open
的模式规范。可能您的版本碰巧禁止写入该地址,因此当您尝试写入该地址时,该进程会崩溃。
顺便说一句:您应该始终检查库调用的返回,例如 shm_open
和 mmap
。
编辑:正如我在下面的评论中所观察到的,您还缺少使用ftruncate
将分段缩放到适当大小。
【讨论】:
谢谢 Jens,我解决了这个问题,但问题仍然存在,sudo ./a.out ; echo $?;
告诉我存在状态是 135。:S
然后给它附加一个调试器,看看它在哪里退出。
正如预期的那样,我到达了这个51 *spool = 3; (gdb) p *spool Cannot access memory at address 0x7ffff7ff9000
啊,我看到的一件事是您没有正确调整段的大小。您需要在某处使用ftruncate
将大小调整为正值。
这似乎有效,请编辑您的原始答案,以便我接受:)以上是关于在 Linux 上写入映射内存时返回带 mmap 的共享内存的主要内容,如果未能解决你的问题,请参考以下文章