C 父进程和子进程之间的Posix共享内存?

C 父进程和子进程之间的Posix共享内存?,c,posix,C,Posix,我正在写一个程序来解决操作系统概念书上的一个练习。这个问题是在子进程上创建一个Collatz猜想,并使用Posix共享memeory将其打印回父进程。这是我的节目 int main(int argc, char* argv[]) { const char* name = "Collatz"; const int SIZE = 4096 * 30; void *ptr; int shm_fd; int num = atoi(argv[1]); pid_t pid; shm_fd = shm_op

我正在写一个程序来解决操作系统概念书上的一个练习。这个问题是在子进程上创建一个Collatz猜想,并使用Posix共享memeory将其打印回父进程。这是我的节目

int main(int argc, char* argv[])
{
const char* name = "Collatz";
const int SIZE = 4096 * 30;
void *ptr;
int shm_fd;
int num = atoi(argv[1]);
pid_t pid;

shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
ftruncate(shm_fd, SIZE);
ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
if (ptr < 0) perror("Ptr error");
pid = fork();
if (pid < 0) perror("Fork Failed");
else if (pid == 0) {
    shm_fd = shm_open(name, O_RDWR, 0666);
    ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
    if (ptr < 0) perror("Ptr error");
    while (num != 1) {
        sprintf(ptr, "%d", num);
        ptr++;
        if (num % 2 == 0) num /= 2;
        else num = 3 * num + 1;
    }
    sprintf(ptr, "%d", num);
    ptr++;
} else {
    wait(NULL);
    printf("Parent: %s\n", (char*) ptr);

    //ptr += sizeof(int);
    shm_unlink(name);
}
return 0;
}
intmain(intargc,char*argv[])
{
const char*name=“Collatz”;
常数int SIZE=4096*30;
无效*ptr;
int shm_fd;
int num=atoi(argv[1]);
pid_t pid;
shm_fd=shm_open(名称,O_create | O_RDWR,0666);
ftruncate(shm_fd,尺寸);
ptr=mmap(0,大小,保护读取,映射共享,shm\u fd,0);
如果(ptr<0)peror(“ptr错误”);
pid=fork();
如果(pid<0)perror(“分叉故障”);
否则如果(pid==0){
shm_fd=shm_open(名称,O_RDWR,0666);
ptr=mmap(0,大小,保护写入,映射共享,shm\u fd,0);
如果(ptr<0)peror(“ptr错误”);
while(num!=1){
sprintf(ptr,“%d”,num);
ptr++;
如果(num%2==0)num/=2;
else num=3*num+1;
}
sprintf(ptr,“%d”,num);
ptr++;
}否则{
等待(空);
printf(“父项:%s\n”,(char*)ptr);
//ptr+=sizeof(int);
shm_取消链接(名称);
}
返回0;
}

但是当我将它与gcc进行比较时,我得到了分段错误(核心转储)。我不知道通过谷歌搜索。我使用Ubuntu 14.04。有人能帮我吗。非常感谢,很抱歉我的英语很差。

我试着用以下代码编译你的代码,它对我有效

#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

输出163518421

这是我的解决方案,希望能对您有所帮助。共享内存通过系统功能mmap(2)加载到进程后面

void∗ mmap(无效∗ 地址、大小长度、整数保护、整数标志、整数fd、关闭偏移)

参数为:
•addr-要加载到进程中的地址(这里通常使用0让内核决定加载到哪里)
•len-加载的内存大小•prot-访问权限(通常为PROTREAD或protwite)
•标志-内存类型(通常为MAPSHARED,以便其他人可以看到进程所做的更改)
•fd-内存对象的描述符
•偏移-共享内存对象中的位置,它将从中重放。
成功执行时,结果是指向加载对象的进程空间中的地址的指针。否则,将返回MAPFAILED值,并将errno设置为适当的值。 请注意,在Linux中,大小必须是页面的倍数:PAGE_size(为此,我使用了getpagesize(2))

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
fprintf(stdout,“起始父级%d\n”,getpid());
内部状态,shm_fd;
char shm_name[]=“collatz”;
结构统计某人;
pid_t pid;
无符号整数位移=0,偏移量=0;
size\u t shm\u size=getpagesize()*(argc-1);
如果(argc<2)
{
fprintf(stderr,“必须至少传递一个参数!”);
退出(退出失败);
}
int*pid_children=(int*)malloc((argc-1)*sizeof(int));
如果(pid_子项==NULL)
{
fprintf(stderr,“内存未分配!”);
出口(1);
}
/*创建共享内存对象*/
shm_fd=shm_open(shm_name,O_CREAT | O|u RDWR,S_IRUSR | S|u IWUSR);
如果(shm_fd<0)
{
perror(空);
返回errno;
}
/*定义大小*/
如果(ftruncate(shm\u fd,shm\u size)=-1){
perror(空);
shm_取消链接(shm_名称);
返回errno;
}
对于(int i=1;i./collatz 12