【问题标题】:How can I prevent background jobs from reading input from terminal?如何防止后台作业从终端读取输入?
【发布时间】:2011-12-07 05:12:38
【问题描述】:

我正在为一个班级编写一个 shell 程序,但遇到了一个我不完全理解的问题。

我必须执行后台作业。 阻止后台作业从终端读取的问题。 我说过的每个资源都不能调用 wait() 但这对我来说是个错误。 现在我有一个小程序,它只是读取输入并重新打印它直到 eof。 在我输入其他命令时在某个时间点 fork 和 exec 之后会发生什么,它开始打印 0

0 0 0 . . .

我遇到了一些建议的解决方案,例如更改进程组 UNIX System call to register a background process

这个解决方案并没有解决我遇到的问题。据我了解,该程序应该得到 SIGTTIN 并停止(我可能误解了这一点)。不幸的是,在后台进程中搜索任何内容都会显示与 shell 脚本相关的页面,而不是与实现相关的页面。

我开始编写一个信号处理程序来捕获 SIGTTIN,但是我不知道此时该做什么。我以为我会使用 kill() 来暂停程序,但是我如何获取尝试读取的进程的 pid。

编辑:我应该提到这个问题是因为我的测试程序将输入读取为 int。但我需要它在读取时阻止它。

编辑:我的简单测试程序是

  cin >> temp;
  do{
    cout << temp << endl;
    cin >> temp;

  }while(!cin.eof());

当它分叉子运行时

  if(PID == 0){
    /*code for checking if IO is redirected*/
    execvpe(args[0], args, curState.getEnv());
    cout << args[0] << " not a command" << endl;
    exit(1);
  }

然后父母检查它是否应该等待

if(jobWait()){
    waitpid(PID, &status, 0);
  }

【问题讨论】:

  • 您使用哪种语言?您能否发布一个您正在使用的代码的简单示例以及如何重现该问题?
  • 它在 C++ 中,我会用一些示例代码更新我的帖子。
  • 在 exec 之前调用 setpgid() 实际上会停止此问题,但是尝试将其置于前台/恢复它时会出现问题
  • 这可能是我做错了,我需要做的是实现 $& 和 fg

标签: unix process background controls jobs


【解决方案1】:

解决了我的问题,如果我正确使用 setpgid(int, int) 则后台应用程序会在尝试读取输入时停止。然后,我可以使用 tcsetpgrp(int, int) 从父进程控制终端,并使用 waitpid(int, &int, int) 等待子进程,只要我处理 SIGCHLD,这样父进程就不会停止child 退出,然后 Parent 可以使用 tcsetpgrp(int, int) 恢复控制

【讨论】:

    猜你喜欢
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 1970-01-01
    相关资源
    最近更新 更多