[linux] 무중단 프로세스 란 무엇입니까?

때로는 Linux에서 프로그램을 작성할 때마다 일종의 버그로 인해 충돌이 발생하면 중단 할 수없는 프로세스가되어 컴퓨터를 다시 시작할 때까지 (로그 아웃하더라도) 영원히 계속 실행됩니다. 내 질문은 :

  • 프로세스가 중단되지 않는 원인은 무엇입니까?
  • 그 일이 일어나지 않게하려면 어떻게해야합니까?
  • 이것은 아마도 멍청한 질문이지만 컴퓨터를 다시 시작하지 않고 중단시킬 수있는 방법이 있습니까?


답변

무정전 프로세스는 신호에 의해 중단 될 수없는 시스템 호출 (커널 기능)에있는 프로세스입니다.

이것이 의미하는 바를 이해하려면 인터럽트 가능한 시스템 호출의 개념을 이해해야합니다. 고전적인 예는 read()입니다. 하드 드라이브를 회전 시키거나 헤드를 움직일 수 있으므로 시간이 오래 걸릴 수있는 시스템 호출입니다. 대부분의 시간 동안 프로세스는 휴면 상태가되어 하드웨어를 차단합니다.

프로세스가 시스템 호출에서 휴면 상태 인 동안 Unix 비동기 신호 (예 : SIGTERM)를 수신 할 수 있으며 다음과 같은 상황이 발생합니다.

  • 시스템 호출이 조기에 종료되며 -EINTR을 사용자 공간으로 리턴하도록 설정됩니다.
  • 신호 처리기가 실행됩니다.
  • 프로세스가 여전히 실행중인 경우 시스템 호출에서 리턴 값을 가져오고 동일한 호출을 다시 수행 할 수 있습니다.

시스템 호출에서 일찍 리턴하면 사용자 공간 코드가 신호에 응답하여 해당 동작을 즉시 변경할 수 있습니다. 예를 들어 SIGINT 또는 SIGTERM에 반응하여 깨끗하게 종료됩니다.

반면에 일부 시스템 호출은 이러한 방식으로 중단 될 수 없습니다. 어떤 이유로 시스템 호출이 중단되는 경우 프로세스는 무한정이 상태로 유지 될 수 있습니다.

LWN은 7 월에이 주제를 다루는 멋진 기사를 작성 했습니다.

원래 질문에 대답하려면 :

  • 이를 방지하는 방법 : 문제를 일으키는 드라이버를 찾아 사용을 중지하거나 커널 해커가되어 수정하십시오.

  • 다시 부팅하지 않고 무중단 프로세스를 종료하는 방법 : 시스템 호출을 종료합니다. 전원 스위치를 누르지 않고 가장 효과적인 방법은 전원 코드를 당기는 것입니다. LWN 기사에 설명 된대로 커널 해커가되어 드라이버가 TASK_KILLABLE을 사용하도록 할 수도 있습니다.


답변

프로세스가 사용자 모드 인 경우 언제든지 중단 할 수 있습니다 (커널 모드로 전환). 커널이 사용자 모드로 돌아 오면 보류중인 신호 ( SIGTERM및 프로세스를 종료하는 데 사용되는 신호 포함)가 있는지 확인합니다 SIGKILL. 이는 사용자 모드로 돌아와야 프로세스가 종료 될 수 있음을 의미합니다.

커널 모드에서 프로세스를 종료 할 수없는 이유는 동일한 시스템에서 다른 모든 프로세스가 사용하는 커널 구조를 잠재적으로 손상시킬 수 있기 때문입니다 (스레드를 종료하면 동일한 프로세스에서 다른 스레드가 사용하는 데이터 구조를 잠재적으로 손상시킬 수 있음) .

커널이 오랜 시간이 걸릴 수있는 작업을 수행해야하는 경우 (예 : 다른 프로세스에서 작성한 파이프를 기다리거나 하드웨어가 작업을 수행 할 때까지 대기하는 경우) 자체를 휴면 상태로 표시하고 스케줄러를 호출하여 다른 프로세스로 전환 프로세스 (비 휴면 프로세스가없는 경우 CPU가 비트 속도를 늦추고 루프 (유휴 루프)에 앉아 있음을 알리는 “더미”프로세스로 전환됨)

신호가 수면 프로세스로 전송되면 사용자 공간으로 돌아 가기 전에 신호를 깨워 보류중인 신호를 처리해야합니다. 여기서 우리는 두 가지 주요 유형의 수면의 차이점이 있습니다.

  • TASK_INTERRUPTIBLE, 중단 가능한 수면. 작업이이 플래그로 표시되어 있으면 작업이 대기 중이지만 신호로 깨울 수 있습니다. 이것은 작업을 잠자기 상태로 표시 한 코드가 가능한 신호를 기대하고 있음을 의미하며, 깨운 후에는이를 확인하고 시스템 호출에서 돌아옵니다. 신호가 처리 된 후 시스템 호출이 자동으로 다시 시작될 수 있습니다 (그 작동 방식에 대한 자세한 내용은 다루지 않겠습니다).
  • TASK_UNINTERRUPTIBLE, 무정전 수면. 작업에이 플래그가 표시되어 있으면 쉽게 다시 시작할 수 없거나 프로그램이 시스템 호출을 원 자성으로 예상하기 때문에 대기중인 것 이외의 다른 작업으로 인해 깨어날 것으로 예상되지 않습니다. 매우 짧은 것으로 알려진 수면에도 사용할 수 있습니다.

TASK_KILLABLE (ddaa의 답변으로 연결된 LWN 기사에 언급)은 새로운 변형입니다.

이것은 첫 번째 질문에 대한 답변입니다. 두 번째 질문에 관해서 : 당신은 무정전 수면을 피할 수 없으며, 그것은 정상적인 일입니다 (예를 들어, 프로세스가 디스크에서 / 디스크로 쓸 때마다 발생합니다). 그러나 그들은 단지 1 초의 시간 동안 지속되어야한다. 그것들이 훨씬 더 오래 지속된다면, 일반적으로 하드웨어 문제 (또는 커널과 동일하게 보이는 장치 드라이버 문제)를 의미합니다. 여기서 장치 드라이버는 결코 일어나지 않을 일을 하드웨어가 기다리고 있습니다. 또한 NFS를 사용 중이고 NFS 서버가 다운되었음을 의미 할 수 있습니다 (서버가 복구되기를 기다리는 중입니다. “intr”옵션을 사용하여 문제를 피할 수도 있습니다).

마지막으로, 복구 할 수없는 이유는 커널이 사용자 모드로 돌아와 신호를 전달하거나 프로세스를 종료 할 때까지 대기하는 것과 같은 이유입니다. 잠재적으로 커널의 데이터 구조가 손상 될 수 있습니다. 프로세스가 종료 될 수있는 사용자 공간으로 돌아 가기 위해; 인터럽트 불가능한 대기 모드에서 대기하는 코드는 오류를 예상하지 않습니다).


답변

인터럽트 불가능한 프로세스는 페이지 결함 이후 I / O를 일반적으로 기다리고 있습니다.

이걸 고려하세요:

  • 스레드는 코어에없는 페이지 (요청로드 된 실행 파일, 스왑 아웃 된 익명 메모리 페이지 또는 요청 된로드 된 mmap () ‘d 파일)에 액세스하려고 시도합니다. 같은 것)
  • 커널은 (로드하려고)
  • 페이지를 사용할 수있을 때까지 프로세스를 계속할 수 없습니다.

이 상태에서는 프로세스 / 작업을 중단 할 수 없습니다. 신호를 처리 할 수 ​​없기 때문입니다. 그럴 경우 다른 페이지 오류가 발생하여 원래 위치로 돌아갑니다.

“process”라고 말하면, 실제로 “task”를 의미합니다. Linux (2.6)에서는 / proc에 개별 “스레드 그룹”항목이 있거나 없을 수있는 “스레드”로 대략 변환됩니다.

경우에 따라 오랫동안 기다리고있을 수 있습니다. 일반적인 예는 실행 파일 또는 mmap’d 파일이 서버가 실패한 네트워크 파일 시스템에있는 경우입니다. I / O가 결국 성공하면 작업이 계속됩니다. 결국 실패하면 작업은 일반적으로 SIGBUS 또는 무언가를 얻습니다.


답변

세 번째 질문으로 :을 실행하여 중단 할 수없는 프로세스를 종료 할 수 있다고 생각합니다
sudo kill -HUP 1. 실행중인 프로세스를 종료하지 않고 init을 다시 시작하고 실행 한 후 중단 할 수없는 프로세스가 사라졌습니다.


답변

“좀비”프로세스 (ps 출력에서 ​​”좀비”로 지정됨)에 대해 이야기하는 경우 프로세스 목록에서 누군가가 리턴 코드를 수집하기를 기다리는 무해한 레코드이므로 안전하게 무시할 수 있습니다.

“무정전 한 프로세스”가 무엇인지 설명해 주시겠습니까? 그것은 “kill -9″에서 살아 남아서 행복하게 포옹합니까? 이 경우 일부 syscall에 멈춰 있으며 일부 드라이버에 갇혀 있으며 재부팅 (때로는 곧 재부팅하는 것이 좋음) 또는 관련 드라이버를 언로드 할 때 까지이 프로세스가 중단됩니다 (발생하지 않을 것입니다) . “strace”를 사용하여 프로세스가 고착 된 위치를 찾아서 나중에 피할 수 있습니다.


답변