【发布时间】:2014-12-19 12:08:54
【问题描述】:
这是一个技术问题,如果你了解 C 和 UNIX,也许你可以帮助我(或者这可能是一个真正的新手问题!)
今天在分析我们的操作系统课程中的一些代码时出现了一个问题。我们正在学习在 UNIX 中“分叉”一个进程意味着什么,我们已经知道它会创建一个与当前进程并行的副本,并且它们具有单独的数据部分。
但后来我想,如果在执行 fork() 之前创建一个变量和一个指向它的指针,因为指针存储了变量的内存地址,那么可以尝试从使用该指针的子进程。
我们在课堂上试过类似这样的代码:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
int main (){
int value = 0;
int * pointer = &value;
int status;
pid_t pid;
printf("Parent: Initial value is %d\n",value);
pid = fork();
switch(pid){
case -1: //Error (maybe?)
printf("Fork error, WTF?\n");
exit(-1);
case 0: //Child process
printf("\tChild: I'll try to change the value\n\tChild: The pointer value is %p\n",pointer);
(*pointer) = 1;
printf("\tChild: I've set the value to %d\n",(*pointer));
exit(EXIT_SUCCESS);
break;
}
while(pid != wait(&status)); //Wait for the child process
printf("Parent: the pointer value is %p\nParent: The value is %d\n",pointer,value);
return 0;
}
如果你运行它,你会得到这样的东西:
父级:初始值为0
孩子:我会尝试改变值
子:指针值为0x7fff733b0c6c
孩子:我已将值设置为 1
父级:指针值为0x7fff733b0c6c
父级:值为0
很明显,子进程根本不影响父进程。坦率地说,我期待一些“分段错误”错误,因为访问了一个不允许的内存地址。但究竟发生了什么?
请记住,我不是在寻找一种与流程通信的方式,这不是重点。我想知道的是代码做了什么。在子进程内部,更改是可见的,所以它做了一些事情。
我的主要假设是指针不是绝对的内存,它们是相对于进程的堆栈。但我一直没能找到答案(班上没有人知道,谷歌搜索我刚刚发现了一些关于流程通信的问题)所以我想从你那里知道,希望有人会知道。
感谢您抽出宝贵时间阅读!
【问题讨论】:
-
你可以把
printf("Parent: the pointer value is %p\nThe value is %d\n",pointer,value);放在switch()的默认情况下 -
"坦率地说,我期待一些“分段错误”错误,因为访问了不允许的内存地址。" 这没有任何意义。想想看。孩子执行的代码是完全合法的。唯一的问题是——它是否会影响父母?
-
在每个进程中,由于每个进程都认为自己拥有所有内存,并且由于动态地址转换,指针是每个进程地址空间中(有效)的相同位置。在子进程中更改值时,您实际上并没有更改父进程中的值。它们是两个不同的(有效的)地址空间。
标签: c unix pointers process fork