답변:
무정전 프로세스는 신호에 의해 중단 될 수없는 시스템 호출 (커널 기능)에있는 프로세스입니다.
이것이 의미하는 바를 이해하려면 인터럽트 가능한 시스템 호출의 개념을 이해해야합니다. 고전적인 예는 read()
입니다. 하드 드라이브를 회전 시키거나 헤드를 움직일 수 있으므로 시간이 오래 걸릴 수있는 시스템 호출입니다. 대부분의 시간 동안 프로세스는 휴면 상태가되어 하드웨어를 차단합니다.
프로세스가 시스템 호출에서 휴면 상태 인 동안 Unix 비동기 신호 (예 : SIGTERM)를 수신 할 수 있으며 다음과 같은 상황이 발생합니다.
시스템 호출에서 일찍 리턴하면 사용자 공간 코드가 신호에 응답하여 해당 동작을 즉시 변경할 수 있습니다. 예를 들어 SIGINT 또는 SIGTERM에 반응하여 깨끗하게 종료됩니다.
반면에 일부 시스템 호출은 이러한 방식으로 중단 될 수 없습니다. 어떤 이유로 시스템 호출이 중단되는 경우 프로세스는 무한정이 상태로 유지 될 수 있습니다.
LWN은 7 월에이 주제를 다루는 멋진 기사를 작성 했습니다.
원래 질문에 대답하려면 :
이를 방지하는 방법 : 문제를 일으키는 드라이버를 찾아 사용을 중지하거나 커널 해커가되어 수정하십시오.
다시 부팅하지 않고 무중단 프로세스를 종료하는 방법 : 시스템 호출을 종료합니다. 전원 스위치를 누르지 않고 가장 효과적인 방법은 전원 코드를 당기는 것입니다. LWN 기사에 설명 된대로 커널 해커가되어 드라이버가 TASK_KILLABLE을 사용하도록 할 수도 있습니다.
프로세스가 사용자 모드 인 경우 언제든지 중단 할 수 있습니다 (커널 모드로 전환). 커널이 사용자 모드로 돌아 오면 보류중인 신호 ( SIGTERM
및 프로세스를 종료하는 데 사용되는 신호 포함)가 있는지 확인합니다 SIGKILL
. 이는 사용자 모드로 돌아와야 프로세스가 종료 될 수 있음을 의미합니다.
커널 모드에서 프로세스를 종료 할 수없는 이유는 동일한 시스템에서 다른 모든 프로세스가 사용하는 커널 구조를 잠재적으로 손상시킬 수 있기 때문입니다 (스레드를 종료하면 동일한 프로세스에서 다른 스레드가 사용하는 데이터 구조를 잠재적으로 손상시킬 수 있음) .
커널이 오랜 시간이 걸릴 수있는 작업을 수행해야하는 경우 (예 : 다른 프로세스에서 작성한 파이프를 기다리거나 하드웨어가 작업을 수행 할 때까지 대기하는 경우) 자체를 휴면 상태로 표시하고 스케줄러를 호출하여 다른 프로세스로 전환 프로세스 (비 휴면 프로세스가없는 경우 CPU가 비트 속도를 늦추고 루프 (유휴 루프)에 앉아 있음을 알리는 "더미"프로세스로 전환됨)
신호가 수면 프로세스로 전송되면 사용자 공간으로 돌아 가기 전에 신호를 깨워 보류중인 신호를 처리해야합니다. 여기서 우리는 두 가지 주요 유형의 수면의 차이점이 있습니다.
TASK_INTERRUPTIBLE
, 중단 가능한 수면. 작업이이 플래그로 표시되어 있으면 작업이 대기 중이지만 신호로 깨울 수 있습니다. 이것은 작업을 잠자기 상태로 표시 한 코드가 가능한 신호를 기대하고 있음을 의미하며, 깨운 후에는이를 확인하고 시스템 호출에서 돌아옵니다. 신호가 처리 된 후 시스템 호출이 자동으로 다시 시작될 수 있습니다 (그 작동 방식에 대한 자세한 내용은 다루지 않겠습니다).TASK_UNINTERRUPTIBLE
, 무정전 수면. 작업에이 플래그가 표시되어 있으면 쉽게 다시 시작할 수 없거나 프로그램이 시스템 호출을 원 자성으로 예상하기 때문에 대기중인 것 이외의 다른 작업으로 인해 깨어날 것으로 예상되지 않습니다. 매우 짧은 것으로 알려진 수면에도 사용할 수 있습니다.TASK_KILLABLE
(ddaa의 답변으로 연결된 LWN 기사에 언급)은 새로운 변형입니다.
이것은 첫 번째 질문에 대한 답변입니다. 두 번째 질문에 관해서 : 당신은 무정전 수면을 피할 수 없으며, 그것은 정상적인 일입니다 (예를 들어, 프로세스가 디스크에서 / 디스크로 쓸 때마다 발생합니다). 그러나 그들은 단지 1 초의 시간 동안 지속되어야한다. 그것들이 훨씬 더 오래 지속된다면, 일반적으로 하드웨어 문제 (또는 커널과 동일하게 보이는 장치 드라이버 문제)를 의미합니다. 여기서 장치 드라이버는 결코 일어나지 않을 일을 하드웨어가 기다리고 있습니다. 또한 NFS를 사용 중이고 NFS 서버가 다운되었음을 의미 할 수 있습니다 (서버가 복구되기를 기다리는 중입니다. "intr"옵션을 사용하여 문제를 피할 수도 있습니다).
마지막으로, 복구 할 수없는 이유는 커널이 사용자 모드로 돌아와 신호를 전달하거나 프로세스를 종료 할 때까지 대기하는 것과 같은 이유입니다. 잠재적으로 커널의 데이터 구조가 손상 될 수 있습니다. 프로세스가 종료 될 수있는 사용자 공간으로 돌아 가기 위해; 인터럽트 불가능한 대기 모드에서 대기하는 코드는 오류를 예상하지 않습니다).
인터럽트 불가능한 프로세스는 페이지 결함 이후 I / O를 일반적으로 기다리고 있습니다.
이걸 고려하세요:
이 상태에서는 프로세스 / 작업을 중단 할 수 없습니다. 신호를 처리 할 수 없기 때문입니다. 그럴 경우 다른 페이지 오류가 발생하여 원래 위치로 돌아갑니다.
"process"라고 말하면, 실제로 "task"를 의미합니다. Linux (2.6)에서는 / proc에 개별 "스레드 그룹"항목이 있거나 없을 수있는 "스레드"로 대략 변환됩니다.
경우에 따라 오랫동안 기다리고있을 수 있습니다. 일반적인 예는 실행 파일 또는 mmap'd 파일이 서버가 실패한 네트워크 파일 시스템에있는 경우입니다. I / O가 결국 성공하면 작업이 계속됩니다. 결국 실패하면 작업은 일반적으로 SIGBUS 또는 무언가를 얻습니다.
"좀비"프로세스 (ps 출력에서 "좀비"로 지정됨)에 대해 이야기하는 경우 프로세스 목록에서 누군가가 리턴 코드를 수집하기를 기다리는 무해한 레코드이므로 안전하게 무시할 수 있습니다.
"무정전 한 프로세스"가 무엇인지 설명해 주시겠습니까? 그것은 "kill -9"에서 살아 남아서 행복하게 포옹합니까? 이 경우 일부 syscall에 멈춰 있으며 일부 드라이버에 갇혀 있으며 재부팅 (때로는 곧 재부팅하는 것이 좋음) 또는 관련 드라이버를 언로드 할 때 까지이 프로세스가 중단됩니다 (발생하지 않을 것입니다) . "strace"를 사용하여 프로세스가 고착 된 위치를 찾아서 나중에 피할 수 있습니다.
TASK_UNINTERUPTIBLE
시스템이 유휴 상태가 아닐 때마다 상태 로 들어가는 프로세스를 시작하도록 프로그램을 작성할 수 있습니까? 따라서 수퍼 유저가 종료되면 전송을 대기하면서 강제로 데이터를 수집 할 수 있습니까? 이것은 해커가 정보를 검색하고 좀비 상태로 돌아가며 유휴 상태에서 네트워크를 통해 정보를 전송하는 금광입니다. 일부는 이것이Blackdoor
원하는대로 시스템에 들어가고 나가는 힘 을 만드는 한 가지 방법이라고 주장 할 수 있습니다 . 나는 'TASK_UNINTERUPTIB