子进程能影响父进程吗?环境?
“孩子继承了父母的环境”是什么意思?通过复制整个环境来继承,还是通过接收指向同一环境的指针来继承(以某种方式)?
这是我的场景:
- 我有一个正在运行的进程
P
,它有自己的环境(变量)。 - 在某个时刻,
P
执行fork
- 在
0
-if-statement
的克隆(又名在子进程C
中),执行execv
- 两个进程都继续运行独立。
因此,在某个时刻,应用程序会停止正常工作。原因就是——“破碎”的环境。
有趣的是,两个环境都发生了变化。当我启动父进程并
$ cat /proc/PID/environ
为父进程和进程执行时,一切都很好。几个小时后,应用程序停止工作,当我再次执行上面的行(以检查环境)时,两者都发生了更改,并且丢失了很多环境变量 - 只有标准变量存在(例如 PWD
、HOME
、USER
等)。
这怎么可能?问题出在哪里——孩子还是父母?
编辑:感谢大家的回答,我的+1,因为它们都是正确的(@caf、@Saphrosit 和 @R..)。这个问题的原因真的很愚蠢..
所有环境变量都放在 /etc/profile
中,该变量在登录后执行(那..我不知道)。
嗯,看来问题是在重新启动机器时发生的。因此,在启动时,应用程序会再次启动,但/etc/profile/
不会执行/读取。这会导致不良行为。这就是为什么在手动重新启动时问题消失的原因 - 一旦 root
登录(通过 ssh
),来自 /etc/profiles
的环境变量被读取,并且当父进程重新启动(由 root
)时,一切都很好 - 环境变量被继承。
愚蠢的错误。
What does "the child inherits the parent's environment" mean? Inherits by copying the whole environment, or inherits by receiving pointer to the same environment (somehow)?
Here's my scenario:
- I have a running process
P
with its own environment (variables) - At some point,
P
executesfork
- In the
0
-clone of theif-statement
(a.k.a. in the child processC
), anexecv
is executed - Both processes continue running independently.
So, in some moment, the application stops working fine. And the reason is - "broken" environment.
The interesting part is, that both environments are changed.. When I start the parent process and execute
$ cat /proc/PID/environ
for both - the parent and the process, everything is fine. Some hours later, the app stops working and when I execute the line above again (to check the environment), both are changed and a lot of environment variables are missing - only the standard ones are there (like PWD
, HOME
, USER
, etc.).
How is this possible? And where could the the problem - in the child or in the parent?
EDIT: Thanks all for the answers, +1 from me, as they were all correct ( @caf, @Saphrosit and @R..). The reason for this issue is really silly..
All environment variables were placed in /etc/profile
which is executed AFTER LOGIN (that.. I didn't know).
Well, it appeared, that the issue have happened on restart of the machine. So, on start-up, the application is started again, but /etc/profile/
is not executed/read. And this causes the bad behavior. And that's why the problem disappears on manual restart - once a root
is logged in (through ssh
), the environment variables from /etc/profiles
are read, and when the parent process is restarted (by root
), it's all fine - the environment variables are inherited.
Stupid mistake.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
子进程在
fork()
时刻继承了父进程环境的副本。任一进程中环境的后续更改不会影响另一个进程。改变这一点的唯一方法是做一些非常奇怪的事情,例如将环境放置在
MAP_SHARED
区域中,或使用ptrace()
。不过,如果你做了这样的事情,你就会知道。The child inherits a copy of the parent's environment at the moment of the
fork()
. Subsequent changes to the environment in either process do not affect the other.The only way you could alter this is by doing something very strange, like placing the environment in a
MAP_SHARED
area, or usingptrace()
. You'd know it if you did something like this, though....或者两者兼而有之?
孩子从其父母环境的副本开始,因此不能影响其父母环境。所以我不认为孩子改变了父亲的环境,但也许父亲改变了他自己的环境。
如果不知道程序到底做了什么,很难说问题出在哪里......
...Or in both?
The child start with a duplicate of his parent environment, so cannot affect his parent one. So I don't think the child changed the environment of the father, but maybe the father changed his own.
Without knowing what exactly the program does it's very hard to say where is the problem...
如果没有更多细节,这个问题实际上几乎不可能回答,但我还是要尝试一下?
您确定调用
fork
时环境的内容实际上有效吗?当然有可能您损坏了内存,但父级此时已经获取并缓存了它所关心的变量的副本,并且只有稍后当它尝试重新获取变量时才会中断。如果是这种情况,孩子的环境也应该被破坏,但孩子可能不在乎......如果这不是问题,工作系统上留下的唯一可能性似乎是父母正在重新启动并且您没有意识到这一点,或者父进程在分叉后破坏了自己的环境。
否则,也许您在损坏的设备上有一个交换分区,并且当它换回时环境被换出并损坏......?
This question is really nearly impossible to answer without more details, but I'm going to take a stab at it anyway?
Are you sure that the contents of the environment are actually valid at the time you call
fork
? It's certainly possible that you corrupted memory but that the parent has already obtained and cached copies of the variables it cares about at this point, and that only later does it break when it tries to re-get one. If this is the case, the environment should be broken in the child too, but the child might not care...If that's not the issue, the only possibilities left on a working system seem to be that either the parent is getting restarted and you're not aware of it, or the parent corrupted its own environment after
fork
ing.Otherwise, perhaps you have a swap partition on a broken device and the environment is getting swapped out and corrupted when it's swapped back in...?