c - 使用 shm_open 将整数从父进程复制到子进程
问题描述
我正在尝试将整数从父进程复制到子进程。许多这种性质的问题都转向使用不同的 IPC 方法。这对我的情况不起作用。解决方案必须使用<sys/shm.h>
. 这是一个更大计划的一部分。我正在初始化大小、指针、pid 和内存名称,如下所示:
const int SIZE = 4*sizeof(int);
const char *name = "OS";
pid_t pid;
int shm_fd;
void *ptr;
我叫叉子
pid = fork();
父进程像这样使用整数
/* 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");
孩子像这样产生整数
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");
这是一个简单的消费者-生产者 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 个是不正确的。我非常感谢任何有关此问题的帮助。
解决方案
I'm afraid there is a typo in pointer arithmetic.
*(int *)(ptr +i)
should be *((int *)ptr+i)
*(int *)(ptr2+i)
should be *((int *)ptr2+i)
It meant "Increment from i
bytes then consider as integer pointer"
instead of
"consider as integer pointer and increment from i
elements".
There is the same problem with memcpy(ptr+i,
that should be
memcpy((int *)ptr+i,
.
An advice: declare immediately ptr
with the correct type,
this will avoid plenty of dangerous casts.
By the way, I cannot see any synchronisation between the child
writing and the parent reading.
Adding an ugly sleep(1);
(don't do this in real life!) before
printf("Parent has received:");
seems to give something correct.
And by another way, depending on the process scheduling, the
shm_open(name, O_RDONLY, 0666);
call in the parent can fail if the
child has not yet called shm_open(name, O_CREAT | O_RDWR, 0666);
(the segment does not exist yet).
推荐阅读
- android - 使用 Kotlin 协程创建 Flowable 等价物
- ssl - 使用 SSL 到上游服务器的 Nginx SSL 代理
- php - 结合html和php
- android - 宽度为毫米的 Android 视图
- powershell - 可以过滤带有结果的特定 OU,但不能过滤另一个?
- python - 子字符串可以重新排列以匹配另一个字符串
- c# - 如何将内连接与 Lambda 表达式一起使用?
- c++ - 在带有 ReSharper 的 VS 中使用 glm::vec3 时出现“不完整类型”警告
- php - 只返回最高的设备维护id
- reactjs - 我将如何规范这个嵌套的减速器案例?