C 在linux上写入映射内存时,使用mmap的共享内存将返回

C 在linux上写入映射内存时,使用mmap的共享内存将返回,c,linux,shared-memory,mmap,C,Linux,Shared Memory,Mmap,我试图找出共享内存,并试图编写一个涉及消费者和生产者的简单程序。我没有到达消费者部分,发现了一个奇怪的小问题:父对象将返回*spool=3没有押韵或理由说明原因。dmesg上没有任何内容 #include <unistd.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h>

我试图找出共享内存,并试图编写一个涉及消费者和生产者的简单程序。我没有到达消费者部分,发现了一个奇怪的小问题:父对象将返回
*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");
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义生产者错误(msg)\
执行{perror(“生产者错误:”msg“\n”);退出(1);}而执行(0)
#定义SHM\U名称“/my\u SharedEM”
无效生产者();
int main(int argc,char*argv[])
{
pid_t pid=fork();
如果(pID==0){
//代码仅由子进程执行
printf(“这里的儿子”);
返回0;
}否则如果(pID<0){
perror(“无法分叉”);
出口(1);
}否则{
//代码仅由父进程执行
printf(“父项在此\n”);
生产者();
返回0;
}
返回0;
}
无效生产者()
{
int-fd,d;
无符号*假脱机;
printf(“已启动\n”);
fd=shm_open(shm_NAME,O|u CREAT | O|u RDWR,S|IRWXU | S|IRWXG | S|IRWXO);//修复
printf(“内存文件已打开\n”);
spool=mmap(NULL,sizeof(无符号),PROT_READ | PROT_WRITE | PROT_EXEC,MAP_SHARED,fd,0);
printf(“mmaped to%p\n\tGonna write.\n”,spool);
perror(空);
*线轴=3;
//msync(spool,sizeof(未签名),MS|u SYNC | MS|u INVALIDATE);
printf(“结束\n”);
}

编辑:修复了shm_打开模式参数

您将模式参数设置为
shm_打开
错误。这应该是
open
的模式规范。可能您的conincidence版本禁止向该地址写入内容,因此当您尝试向该地址写入内容时,该过程会崩溃

顺便说一句:您应该始终检查库调用的返回,例如
shm\u open
mmap


编辑:正如我在下面的一条评论中所观察到的,您也缺少使用
ftruncate

将段缩放到适当大小的功能。您将模式参数设置为
shm_open
错误。这应该是
open
的模式规范。可能您的conincidence版本禁止向该地址写入内容,因此当您尝试向该地址写入内容时,该过程会崩溃

顺便说一句:您应该始终检查库调用的返回,例如
shm\u open
mmap


编辑:正如我在下面的一条评论中所观察到的,您也无法使用
ftruncate

将段缩放到适当的大小。使用shm\u open获得的对象大小为零。你需要为它分配一些空间。mmap将允许您映射超出其大小的内容(shm对象和文件),但当您访问该内存时,您将崩溃

在shm_open之后,您要做的是:

ftruncate(fd, <the size you want>);
ftruncate(fd,);

如果mmap让你的船漂浮,你也可以在mmap之后完成。

打开shm_时得到的对象大小为零。你需要为它分配一些空间。mmap将允许您映射超出其大小的内容(shm对象和文件),但当您访问该内存时,您将崩溃

在shm_open之后,您要做的是:

ftruncate(fd, <the size you want>);
ftruncate(fd,);

如果mmap能让你的船浮起来,你也可以在mmap之后做。

谢谢你,Jens,我已经解决了这个问题,但问题仍然存在,
sudo./a.out;echo$告诉我存在状态为135:然后给它附加一个调试器,看看它从哪里释放出来;(gdb)p*spool无法访问地址0x7ffff7ff9000处的内存,我看到的一件事是您没有正确调整段的大小。你需要一个
ftruncate
的地方来调整大小,使之达到积极的效果。这似乎奏效了,请编辑你的原始答案,以便我可以接受:)谢谢你,Jens,我已经解决了这个问题,但问题仍然存在,
sudo./a.out;echo$告诉我存在状态为135:然后给它附加一个调试器,看看它从哪里释放出来;(gdb)p*spool无法访问地址0x7ffff7ff9000处的内存,我看到的一件事是您没有正确调整段的大小。您需要一个
ftruncate
的地方来调整大小,使之达到积极的效果。这似乎有效,请编辑您的原始答案,以便我可以接受:)