1

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

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()打电话时,哪个应用程序正在读取它?主应用程序还是my_other_app我启动的应用程序execv

编辑:它通过测试my_other_app优先于控制台出现。每次都会出现这种情况吗?有没有办法确保控制台由主进程拥有?

4

3 回答 3

4

两个进程都stdin连接到终端(或任何原始进程stdin连接到的)。当您调用时,这不会改变execv。如果两个进程同时尝试读取stdin,则无法预测哪一个会获得输入。

如果要断开子进程与终端的连接,则应在调用setsid()之前调用execv以将其置于自己的会话中并删除其控制终端。

于 2014-02-01T03:14:07.030 回答
2

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

您有两个解决方案,只需在子进程中关闭stdin,但这可能会导致问题,或者将其替换为/dev/null.

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

您可以对stdoutstderr执行相同的操作。


在程序末尾添加“永远等待”(因为您不能再执行 getchar() 了):

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

这可能是最简单的方法,还有很多其他方法,例如在您知道永远不会改变的文件上使用 select() ...

于 2014-02-01T03:57:16.507 回答
1

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

于 2014-02-01T03:16:17.540 回答