LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1308|回复: 6

fork问题:为什么父进程的shell可以用,而子进程的不行?

[复制链接]
发表于 2007-6-13 16:55:31 | 显示全部楼层 |阅读模式
大家好,请教你们一个 问题:
先请看两个简单的程序:

一:

/*父进程execl后的shell可以用*/
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
        if(fork())
        {
                execl("/bin/sh","sh",0);
        }
        else
        {
                printf("child process is printing.\n");
                exit(0);
        }
}

二:

/*子进程execl后的shell只能接受一个字符*/
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
        if(fork()==0)
        {
                execl("/bin/sh","sh",0);
        }
        else
        {
                printf("parent process is printing.\n");
                exit(0);
        }
}

这个是什么原因呢?
发表于 2007-6-13 18:16:30 | 显示全部楼层
我的理解是:
在1中,父进程运行一个sh,子进程很快退出。原来的shell,比如说bash,将等待这个程序结束。即等待父进程的sh运行结束。所以父进程的sh可用。
在2中,父进程挂求了,子进程就变成了孤儿,同时,原来那个bash由于晓得父进程已经退出了,就回到前台来了。而子进程的sh却在后台运行。所以子进程得不到输入。除非在父进程里面添加wait(),使它等待子进程,这样子进程的sh就可以很正常地跑。

至于为什么会出现子进程的sh可以得到一个字符,就不知道了。猜测应该和输入输出诡异的特性有关。端个板凳等解答。
回复 支持 反对

使用道具 举报

发表于 2007-6-13 21:08:05 | 显示全部楼层
父进程退出了~  你让它wait就Ok了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-6-14 09:00:36 | 显示全部楼层
Post by 墟里烟
除非在父进程里面添加wait(),使它等待子进程,这样子进程的sh就可以很正常地跑。
Post by gradetwo
父进程退出了~  你让它wait就Ok了

恩,加个wait()就行了,谢谢!又加多对多进程的理解了。

一般教材上的知识都有涉及到进程等待的,但是我还是有很多没弄明白。
就是不明白:如果fork出一个子进程做其他与父进程不相关的事,为什么要等待。

到底一个多进程程序中如果父进程退出了对子进程有什么影响呢(子进程已经exec的情况下)?就像上面提到的第2个程序一样是怎么回事呢?
回复 支持 反对

使用道具 举报

发表于 2007-6-15 03:36:22 | 显示全部楼层
我的理ã是需要同步的时候才等待,如果子进程做的工作跟父进程无关,而父进程又不关心子进程的结束状态,就不需要等待了,孤儿进程都由init领养
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-6-15 09:15:47 | 显示全部楼层
Post by wawxdyy
我的理ã是需要同步的时候才等待,如果子进程做的工作跟父进程无关,而父进程又不关心子进程的结束状态,就不需要等待了,孤儿进程都由init领养


那第2个程序只能得到一个字符输入如何解释呢?与预计的运行结果不符呀?
回复 支持 反对

使用道具 举报

发表于 2007-6-16 13:34:00 | 显示全部楼层
Post by amang
£第2个程序êý—到一个字符输入如何解释呢?与预计的运行结果不符呀?

这种情况就属于需要同步的情况,因为如果父进程结束了的话,子进程就会变成孤儿进程了。有的系统在fork后子进程会先运行,而有的系统则是父进程先运行,你的系统就是属于前者(sh被运行两次):

  1. space@space:~$ ./a.out
  2. $ parent process is: not found
  3. $ lse@space:~$ sh:
  4. a.c  a.out  bash.man  Desktop  work
复制代码

看到了吗,先出现子进程sh的提示符,然后打印父进程信息,然后我再ls,就会先提示“parent process is: not found”,然后再运行ls
而如果是父进程先运行,那么子进程就直接变成孤儿进程了(sh只被运行一次)。
至于为什么只能接收一个字符(应该是一个命令吧?),我的理解是,子进程先获得了控制终端,然后父进程结束,接下来在子进程获得输入的时候,shell得知子进程已经变成孤儿进程了,所以子进程的sh只能运行一次就退出了。(执行两次是因为第一次的时候还不是孤儿进程)
PS:我也是初学,有些地方难免有偏差,莫见笑
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表