如果我fork()然后做一个execv(),谁拥有控制台?

我正在编写一个Linux应用程序。 如果我调用fork() ,然后运行一个需要控制台input的应用程序,会发生什么? 考虑下面的代码:

 int process_id = fork(); if (process_id != 0) { /* this is the parent process */ error = execv("../my_other_app", "parameter1", NULL); if (error < 0) { printf("error!"); } } else { /* this is the child process. Wait for my_other_app to set up */ sleep(3); /* now continue */ } printf("########## press ENTER to stop ##########\n"); getchar(); exit(0); 

事情是, my_other_app也有一个按ENTER键来停止消息。 所以当我做getchar()调用时,哪个应用程序正在读取它? 主应用程序还是我用execv启动的my_other_app

编辑:它通过testing显示my_other_app优先于控制台。 这是否每次都发生? 有没有办法确保控制台由主进程拥有?

Solutions Collecting From Web of "如果我fork()然后做一个execv(),谁拥有控制台?"

这两个进程都有他们的stdin连接到终端(或任何原始进程的stdin连接到)。 当你调用execv时,这不会改变。 如果两个进程都试图同时从stdin读取,那么哪一个会得到输入是不可预知的。

如果你想从终端断开子进程,你应该在调用execv之前调用setsid()把它放到自己的会话中,并删除它的控制终端。

fork()在每个文件描述符上调用dup() 。 实际上你得到了孩子所有文件的副本。 一些“进程”(通过钩子)可能会检测到fork()并关闭一些文件描述符,但这是不太可能的。 某些文件可能会打开一个特定的标志,说它应该关闭execv()stdin不是其中之一。

你有两个解决方案,只是在子进程中关闭stdin ,但是这可能会导致问题,或者用/dev/null替换它。

 freopen("/dev/null", "r", stdin); 

你可以为stdoutstderr做同样的事情。


在程序的最后添加一个'永远等待'(因为你不能再getchar()了):

 for(;;) sleep(0x7FFFFFFF); // for(;;) is probably superfluous 

这可能是最简单的方法,还有很多其他的方法,比如在一个你永远不会改变的文件上使用select()。

我认为它似乎似乎my_other_app有优先权,因为其他子进程已经sleep(3)