Bash의 작업 제어는 중지되거나 종료된 백그라운드 작업을 어떻게 처리합니까?

Bash의 작업 제어는 중지되거나 종료된 백그라운드 작업을 어떻게 처리합니까?

Linux에서 bash 작업 제어 메커니즘의 내부 구조를 연구하는 동안 이해에 작은 문제가 발생했습니다. 다음 시나리오를 가정해 보겠습니다.

스크립트는 백그라운드에서 실행됩니다.
user@linux:~# ./script.sh &

동일한 스크립트가 포그라운드에서 동시에 실행됨
user@linux:~# ./script.sh

이제 포그라운드에서 스크립트를 두 번째 실행하는 동안 스크립트의 첫 번째 실행이 백그라운드 작업으로 실행됩니다. 이제 Bash는 종료될 때까지 포그라운드 프로세스의 PID를 사용하여 차단 대기 호출을 수행한 다음 적절한 정보를 얻습니다. 포그라운드 프로세스가 종료된 후 bash는 모든 백그라운드 작업의 상태를 제어하고 프롬프트로 돌아가기 전에 각 변경 사항을 알립니다. 이는 일반적으로 "+b"라는 기본 동작입니다.

그러나 "-b"라는 또 다른 모드가 있습니다. 이 모드에서는 모든 백그라운드 작업 상태 변경이 bash에 즉시 통보됩니다. 내가 이해한 바에 따르면 이는 SIGCHLD 신호를 백그라운드 프로세스로 보내는 방식으로 수행됩니다. 그러나 bash는 차단 대기 호출을 수행함에도 불구하고 백그라운드 프로세스를 종료하고 터미널에 메시지를 인쇄하는 신호에 어떻게 반응합니까? 왜냐하면 신호는 사용자 모드로 돌아가기 전에만 처리되는 것 같기 때문입니다.
bash 호출은 현재 전경이 종료될 때까지 WNOHANG 옵션을 사용하여 루프에서 대기합니까?

또한 "-b" 모드에서 실행될 때 bash는 터미널의 포그라운드 프로세스 그룹의 일부가 아니더라도 터미널에 쓸 수 있습니다. stty를 사용하여 "tostop" 옵션을 설정하더라도 bash는 포그라운드 프로세스 그룹에 속하지 않고도 터미널에 쓸 수 있습니다. bash는 터미널 제어 프로세스 그룹의 일부이므로 특별한 권한을 얻습니까?

내 이해에 문제가 있는 부분을 알아낼 수 있기를 바랍니다.

답변1

예, 루프에서 함께 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 ~해야 한다이 작업을 수행하는 셸에 영향을 줍니다.

관련 정보