以下是我从https://github.com/karelzak/util-linux/blob/200769b6c0dff6863089ea2a9ff4ea9ccbd15d0f/login-utils/login.c#L939了解到的wait()
和exit()
的一些用法
f(){
child_pid = fork();
if (child_pid) {
// parent part
...
while (wait(NULL) == -1 && errno == EINTR) ;
...
exit();
}
// common part, which is actually child part
...
}
f();
// common part 2, which is actually child part
...
与
相同吗f(){
child_pid = fork();
if (child_pid) {
// parent part
...
while (wait(NULL) == -1 && errno == EINTR) ;
...
exit();
}
if (child_pid == 0) {
// common part, which is actually child part
...
// common part 2, which is actually child part
...
}
}
f();
?
第二个比第一个更容易理解吗? That is what I feel (especially the above code is wrapped in a function, and a call to that function has other common code following it in main()
),但我对此并不了解。
是否有任何理由或情况使第一个比第二个更好?
特别是,为什么login
(上面的第一个链接)的实现选择第一种方式?
谢谢。
答案 0 :(得分:1)
这实际上是一个关于什么属于函数的问题,有些模糊。但是,如果您的功能类似于“将我带入以某种特定方式设置了环境的新流程”,则该代码具有如下结构是合理的:
void switch_to_child(){
int pid = fork();
if (pid < 0){
exit_with_an_error();
}
if (pid > 0){
wait_and_exit_in_parent();
}
set_up_child_environment();
}
initialize_stuff();
switch_to_child();
do_child_stuff();
另一方面,如果您的函数类似于“生成一个新进程来执行某件事”,那么代码具有如下结构就更有意义:
void make_child(){
int pid = fork();
if (pid < 0){
exit_with_an_error();
}
if (pid == 0){
do_child_stuff();
exit_in_child();
}
}
initialize_stuff();
make_child();
wait_and_exit_in_parent();