使用 shm_open 将整数从 parent 进程复制到 child 进程

using shm_open to copy integers from parent process to child process

我正在尝试将整数从 parent 进程复制到 child 进程。许多这种性质的问题被重定向到使用不同的 IPC 方法。这对我的情况不起作用。解决方案必须使用 <sys/shm.h>。这是一个更大程序的一部分。我正在初始化大小、指针、pid 和内存名称,如下所示:

          const int SIZE = 4*sizeof(int);
          const char *name = "OS";
          pid_t pid;
          int shm_fd;
          void *ptr;

我叫fork

pid = fork();

parent 进程像这样消耗整数

                  /* open the shared memory segment */
                  shm_fd = shm_open(name, O_RDONLY, 0666);
                  if (shm_fd == -1) {
                          fprintf(stderr,"open shared memory failed\n");
                          exit(-1);
                  }

                  /* now map the shared memory segment in the address space of the process */
                  ptr = mmap(0,SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
                  if (ptr == MAP_FAILED) {
                          fprintf(stderr,"Map failed in parent\n");
                          exit(-1);
                  }
                  printf("Parent got mapped pointer: %p\n",ptr);
                  /* now read from the shared memory region */
                  printf("Parent has received:");
                  for(int i=0; i < SIZE/sizeof(int); i++)
                        printf(" %d ", *(int *)(ptr +i));
                  printf("\n");

                  /* remove the shared memory segment */
                  if (shm_unlink(name) == -1) {
                          fprintf(stderr,"Error removing %s\n",name);
                          exit(-1);
                  }
                  printf("parent done\n");

child 生成像这样的整数

                  printf("In Child process. I am the producer: my pid=%d\n",getpid());
                  time_t t;
                  srand(time(&t));
                  int integers[SIZE];
                  printf("Generating random integers: ");
                  for(int i=0; i < SIZE/sizeof(int); i++){
                          int value = (rand() -49) %49;
                          integers[i] = value;
                          printf(" %d ", value);
                  }
                  printf("\n");


                  /* create the shared memory segment */
                  shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
                  if (shm_fd == -1) {
                          fprintf(stderr,"open shared memory failed\n");
                          exit(-1);
                  }

                  /* configure the size of the shared memory segment */
                  ftruncate(shm_fd,SIZE);

                  /* now map the shared memory segment in the address space of the process */
                  ptr = mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
                  if (ptr == MAP_FAILED) {
                          fprintf(stderr,"Map failed in child\n");
                          return -1;
                  }
                  printf("Child got mapped pointer: %p\n",ptr);
                  void *ptr2=ptr;//back up the pointer for later use
                  /* Now write to the shared memory region. Increment the value of ptr after each write. */
                  memcpy(ptr, integers, sizeof(int));
                  memcpy(ptr+1,integers+1, sizeof(int));
                  memcpy(ptr+2,integers+2, sizeof(int));
                  memcpy(ptr+3,integers+3, sizeof(int));

                  printf("Child has sent: ");
                  for(int i=0; i < SIZE/sizeof(int); i++)
                          printf(" %d ", *(int *)(ptr2+i));
                  printf("\n");

这是一个简单的 consumer-producer IPC 程序,但由于某些原因,当我 运行 该程序时,我的输出不正确。例如,当我生成一组整数时,我得到

In Parent process. I am the consumer: my child pid=19187
In Child process. I am the producer: my pid=19187
Generating random integers:  8  10  37  48
Child got mapped pointer: 0x7f91c9c09000
Child has sent:  807733768  3155210  12325  48
Parent got mapped pointer: 0x7f91c9c09000
Parent has received: 807733768  3155210  12325  48
parent done

看起来最后一个内存位置是有效的,但前 3 个不正确。我将非常感谢对这个问题的任何帮助。

恐怕指针运算有误。
*(int *)(ptr +i) 应该是 *((int *)ptr+i)
*(int *)(ptr2+i) 应该是 *((int *)ptr2+i)

意思是"Increment from i bytes then consider as integer pointer" 代替 "consider as integer pointer and increment from i elements".

memcpy(ptr+i,有同样的问题应该是 memcpy((int *)ptr+i,.

一个建议:立即ptr声明正确的类型, 这将避免大量危险的 casts.

顺便说一下,我看不到 child 之间有任何同步 写作和 parent 阅读。
添加丑陋的 sleep(1); (现实生活中不要这样做!) printf("Parent has received:"); 似乎给出了正确的东西。

换句话说,根据进程调度, shm_open(name, O_RDONLY, 0666); 在 parent 中的调用可能会失败,如果 child 还没有打电话给 shm_open(name, O_CREAT | O_RDWR, 0666); (该段尚不存在)。