如果我在子进程中输入一些内容,fork 和 exec 组合将不起作用
fork and exec combination not working if I take some input in child process
我写了一个 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
child 在其 parent 死亡后试图从终端读取。这不起作用,因为 child 不再在前台进程组中。
好的,什么是前台进程组?基本思路是一个process group the set of processes that are in the same shell job. When you run a program from a shell in a terminal, the shell creates a process group for that program. If the program forks, the children belong to the same process group. If you run the program in the background (myprogram &
), the process group is a background process group; if you run the program in the foreground (without &
) then the process group is the foreground process group(只能有一个前台进程组)。 shell 命令 fg
和 bg
可以将进程组带入前台或后台。进程组用于两件事:您可以将它们一起发信号,它们决定允许谁访问终端。
只允许前台进程组从终端读取。如果后台进程试图从终端读取,read
系统调用 returns EIO
。这是一个用户界面设计决策:当用户在前台与程序交互时,后台进程不会中断它。
让我们检测 child 以打印有关其进程组的信息:
#!/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
child的进程组还是parent的进程ID,但是parent已经死了(所以现在parent的进程ID child 是 1)。因此 child 现在在它自己的进程组中。由于不在前台(shell现在回到前台),child在后台,所以无法访问终端。
对比在 print("I am parent")
之前添加对 os.wait()
的调用会发生什么:
$ ./parent.py
Child: pid=15619 ppid=15618 pgid=15618
enter a no : hello
I am child hello
I am parent
这次child还在前台进程组,所以可以正常访问终端
我不知道为什么 Python 将错误报告为 EOFError
而不是 IOError
。
我写了一个 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
child 在其 parent 死亡后试图从终端读取。这不起作用,因为 child 不再在前台进程组中。
好的,什么是前台进程组?基本思路是一个process group the set of processes that are in the same shell job. When you run a program from a shell in a terminal, the shell creates a process group for that program. If the program forks, the children belong to the same process group. If you run the program in the background (myprogram &
), the process group is a background process group; if you run the program in the foreground (without &
) then the process group is the foreground process group(只能有一个前台进程组)。 shell 命令 fg
和 bg
可以将进程组带入前台或后台。进程组用于两件事:您可以将它们一起发信号,它们决定允许谁访问终端。
只允许前台进程组从终端读取。如果后台进程试图从终端读取,read
系统调用 returns EIO
。这是一个用户界面设计决策:当用户在前台与程序交互时,后台进程不会中断它。
让我们检测 child 以打印有关其进程组的信息:
#!/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
child的进程组还是parent的进程ID,但是parent已经死了(所以现在parent的进程ID child 是 1)。因此 child 现在在它自己的进程组中。由于不在前台(shell现在回到前台),child在后台,所以无法访问终端。
对比在 print("I am parent")
之前添加对 os.wait()
的调用会发生什么:
$ ./parent.py
Child: pid=15619 ppid=15618 pgid=15618
enter a no : hello
I am child hello
I am parent
这次child还在前台进程组,所以可以正常访问终端
我不知道为什么 Python 将错误报告为 EOFError
而不是 IOError
。