在研究bash在Linux下的作业控制机制的内部过程中,我遇到了一个小小的理解问题。让我们假设以下场景:
脚本在后台执行。
user@linux:~# ./script.sh &
在前台同时执行相同的脚本。
user@linux:~# ./script.sh
现在,在前台执行脚本的第二次执行期间,脚本的第一次执行作为后台作业执行。Bash现在使用前景进程的PID执行阻塞等待调用,直到它终止,然后得到相应的信息。在forground进程结束后,bash控制所有后台作业的状态,并在返回到提示符之前通知所有更改。这通常是名为"+b“的默认行为。
但是还有另一种叫做"-b“的模式。在这种模式下,bash会立即通知每个后台作业状态的更改。据我理解,这是通过后台进程发送信号SIGCHLD完成的。但是,bash如何对终止的后台进程的信号作出反应,并在终端执行阻塞等待调用的情况下将消息打印到终端。因为在我看来,信号只能在返回用户模式之前处理。
bash调用是否在循环中使用WNOHANG选项等待,直到当前前景结束?
此外,在运行模式下,"-b“bash可以写入终端,尽管它不属于终端的前台进程组。即使当我用stty设置选项"tostop“时,bash也可以写入终端,而无需成为前台进程组的一部分。bash是否获得任何特殊权限,因为它是终端控制进程组的一部分。
我希望,我能弄清楚我的理解问题在哪里。
发布于 2018-04-13 06:57:54
是的,bash在循环中使用waitpid()和WNOHANG。您可以请看这个waitchld()在……里面jobs.c:
static int
waitchld (wpid, block)
pid_t wpid;
int block;
{..。
do
{
/* We don't want to be notified about jobs stopping if job control
is not active. XXX - was interactive_shell instead of job_control */
waitpid_flags = (job_control && subshell_environment == 0)
? (WUNTRACED|wcontinued)
: 0;
if (sigchld || block == 0)
waitpid_flags |= WNOHANG;..。
if (block == 1 && queue_sigchld == 0 && (waitpid_flags & WNOHANG) == 0)
{
internal_warning (_("waitchld: turning on WNOHANG to avoid indefinite block"));
waitpid_flags |= WNOHANG;
}
pid = WAITPID (-1, &status, waitpid_flags);..。
/* We have successfully recorded the useful information about this process
that has just changed state. If we notify asynchronously, and the job
that this process belongs to is no longer running, then notify the user
of that fact now. */
if (asynchronous_notification && interactive)
notify_of_job_status ();
return (children_exited);
}这个notify_of_job_status()函数只是简单地写入bash进程的标准错误流。
不幸的是,对于使用tostop设置stty是否应该影响您所使用的shell,我不能说太多。
https://unix.stackexchange.com/questions/437414
复制相似问题