如果我在子进程中输入一些输入,fork和exec组合不起作用

时间:2015-02-21 12:08:11

标签: python io terminal fork

我写了一个python代码,其中一个进程使用fork()创建另一个进程。在子进程中,我想使用execlp()打开另一个进程。

我在子进程中打开的程序显示 EOF 错误。我不明白为什么,因为当我尝试单独运行该子程序时,它没有显示任何错误。

对于主要进程,Python代码是

import os  
def main():  
        pid=os.fork()  
        if pid==0:  
                os.execlp("python3", "python3", "child1.py")  
        else:  
                print("I am parent")  
main() 

对于子进程,代码是

def main():  
  a=input("enter a no : ")  
  print("I am child "+str(a))  
main() 

我打开主程序或父进程时得到的输出

I am parent
debesh@laptop:~/Documents/programs/python/parallel_processes$ enter a no : Traceback (most recent call last):
  File "child1.py", line 5, in <module>
    main()
  File "child1.py", line 2, in main
    a=input("enter a no : ")
EOFError

1 个答案:

答案 0 :(得分:4)

孩子在父母去世后试图从终端阅读。这不起作用,因为孩子不再在前台进程组中。

好的,什么是前台进程组?基本思想是process group处于同一shell作业中的一组进程。当您从终端中的shell运行程序时,shell会为该程序创建一个进程组。如果程序分叉,则子项属于同一进程组。如果您在后台运行该程序(myprogram &),则该进程组为background process group;如果您在前台运行程序(没有&),那么进程组是foreground process group(只能有一个前台进程组)。 shell命令fgbg可以将进程组带入前台或后台。进程组用于两件事:您可以一起发出信号,然后确定允许谁访问终端。

只允许前台进程组从终端读取。如果后台进程尝试从终端读取,则read系统调用将返回EIO。这是一个用户界面设计决策:当用户与前台的程序进行交互时,后台进程不会破坏它。

让孩子记录有关其过程组的信息:

#!/usr/bin/python3
import os
def main():  
  print("Child: pid={pid:d} ppid={ppid:d} pgid={pgid:d}".format(pid=os.getpid(), ppid=os.getppid(), pgid=os.getpgrp()))
  a=input("enter a no : ")  
  print("I am child "+str(a))  
main() 

示例输出:

$ ./parent.py 
I am parent
$ Child: pid=15593 ppid=1 pgid=15592
enter a no : Traceback (most recent call last):
  File "child1.py", line 7, in <module>
    main() 
  File "child1.py", line 5, in main
    a=input("enter a no : ")  
EOFError

子进程的进程组仍然是父进程的进程ID,但父进程已经死掉(所以现在子进程的父进程ID为1)。因此,孩子现在处于自己的过程组中。因为它不在前台(shell现在回到前台),所以孩子在后台,所以它无法访问终端。

对比如果您在os.wait()

之前添加对print("I am parent")的来电,会发生什么情况
$ ./parent.py 
Child: pid=15619 ppid=15618 pgid=15618
enter a no : hello
I am child hello
I am parent

这次孩子仍在前台进程组中,因此它可以按预期访问终端。

我不知道为什么Python会将错误报告为EOFError而不是IOError