【问题标题】:How does shell(bash) works in linux i.e How it handles background running processshell(bash)如何在linux中工作,即它如何处理后台运行进程
【发布时间】:2015-11-22 10:12:09
【问题描述】:

这是我的代码:

#include<stdio.h>
#include<signal.h>
void my_isr();
int main()
{
    signal(SIGALRM,my_isr);
    alarm(5);
    pause();
    printf("in main()...\n");//case2 comments it //case 1 & 3 uncomments it
    return 0;//case 1 & 2 comments this line // case 3 uncomment it
}
void my_isr()
{
    printf("I am in my_isr()\n");
}

如果我在后台运行进程

案例 1 :如果我在 main 作用域末尾的 main 函数中没有 return 0,它(shell-bash)会打印 exit 值 13(最后一个 printf 中的可打印字符数)。为什么只有最后一个 printf ?它是未定义的行为吗?

xyz@xyz-PC:~/s_flow$ ./a.out &
[1] 9158
xyz@xyz-PC:~/s_flow$ I am in my_isr()
in main()...

[1]+  Exit 13                 ./a.out

然后shell打印Exit,状态值为13

案例 2 :如果 main() 末尾没有 return 0 并且我删除了 last printf(打印 13 个字符)

xyz@xyz-PC:~/s_flow$ ./a.out &
[1] 9169
xyz@xyz-PC:~/s_flow$ I am in my_isr()

[1]+  Exit 255                ./a.out

然后shell打印退出状态值为255。如何?

案例 3:最后,如果所有内容都正确提供,即如果我在 main() 末尾提及 return 0,则 shell 打印的 Done 消息没有任何价值。

xyz@xyz-PC:~/s_flow$ ./a.out &
[1] 9178
xyz@xyz-PC:~/s_flow$ I am in my_isr()
in main()...

[1]+  Done                    ./a.out

我大致了解为什么 bash shell 会打印 Exit 13Exit 255Done,但欢迎提供任何进一步的解释。我真正的问题是,当一个进程在后台运行时,shell 如何与操作系统交互,我可以在哪里找到这些 shell 消息?以及OS 如何将这些状态值返回给shell & 然后 shell 打印?任何帮助表示赞赏。提前致谢。

【问题讨论】:

  • 如果您编译时包含所有警告和调试信息 (gcc -Wall -Wextra -g),您将收到有用的警告,您可以在 gdb 调试器中调试您的程序。另外,请阅读signal(7)time(7);禁止在信号处理程序内调用printf

标签: c linux


【解决方案1】:

13 是程序的结果代码。它在两种情况下都以结果代码 13 终止 - 当它同时在后台和前台运行时。但是当程序在前台运行时,bash 不会打印结果代码。但是您可以检查结果代码实际上是 13 用于前台运行:

$ ./a.out
in isr() 16664:..
in isr() 16664:..
in main()...
$ echo $?
13

为什么是 13?结果代码通常是main() 函数的结果代码。但是main() 函数不包含任何返回语句,因此结果取决于体系结构。在这种情况下,值 13 是上次 printf 调用的返回值,因为

printf("in main()...\n");

返回 13 打印字符串的长度。并且值 13 偶然保留在寄存器中。

【讨论】:

  • 哇,兄弟!我以为我错过了一些东西..你发现了谢谢
【解决方案2】:

“随机”退出代码是由于 main() 的返回类型不正确造成的。 main() 应该返回 int,这是返回给调用环境的值。

当一个后台进程完成时,它的关联终端会被通知完成及其退出状态。但是您的程序没有正确发送其退出状态。这在技术上是undefined behaviour

【讨论】:

  • 我放入了 int main(),但它仍然显示 ..ok 如果我将 exit(0) 放入 my_isr 然后在暂停后任何语句都没有执行 .. 如何打印最后一个 printf 语句
  • 您不能从信号处理程序中exit()。与printf() 相同。您不能调用不是信号安全的函数。有关安全功能的列表,请参阅async signal safe functions。在 C99 之前,main() 需要显式返回一个 int。从 C99 开始,隐式返回零,并且不需要您显式调用 exit()return 值。因此,如果您使用 C89/C90,您可能需要 returnexit()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-24
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2012-09-20
  • 2013-09-07
相关资源
最近更新 更多