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


156

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

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

TASK_UNINTERUPTIBLE시스템이 유휴 상태가 아닐 때마다 상태 로 들어가는 프로세스를 시작하도록 프로그램을 작성할 수 있습니까? 따라서 수퍼 유저가 종료되면 전송을 대기하면서 강제로 데이터를 수집 할 수 있습니까? 이것은 해커가 정보를 검색하고 좀비 상태로 돌아가며 유휴 상태에서 네트워크를 통해 정보를 전송하는 금광입니다. 일부는 이것이 Blackdoor원하는대로 시스템에 들어가고 나가는 힘 을 만드는 한 가지 방법이라고 주장 할 수 있습니다 . 나는 'TASK_UNINTERUPTIB
Nuuwski

2
코드를 공유하십시오?
다시

답변:


198

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

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

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

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

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

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

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

원래 질문에 대답하려면 :

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

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


31
랩톱에서 전원 코드를 뽑았는데 슬프게도 작동하지 않습니다. ;-)
thecarpy

1
EAGAIN 대신 EINTR 아닌가요? 또한 read ()는 -1을 반환하고 errno는 오류로 설정됩니다.
lethalman

2
@Dexter : 실제로 요점을 놓치고 있습니다. LWN 기사 : lwn.net/Articles/288056을 읽으십시오 . 이러한 문제는 게으른 장치 드라이버 프로그래머에 의해 발생하며 장치 드라이버 코드에서 수정해야합니다.
ddaa

4
@ddaa "Unix 전통 (그리고 거의 모든 응용 프로그램)은 파일 저장소 쓰기가 신호를 인터럽트 할 수없는 것으로 믿습니다. 보증을 변경하는 것이 안전하거나 실용적이지는 않습니다." -> 이것은이 모든 IMO에서 가장 잘못된 부분입니다. 드라이버의 읽기 / 쓰기 요청을 중단하고 실제 장치 (하드 디스크 / 네트워크 카드 등)가 데이터를 전달할 때는 무시하십시오. OS 커널은 개발자가이를 망칠 수없는 방식으로 만들어야합니다.
덱스터

2
@ddaa 나는 리눅스가 마이크로 커널이 아니라는 것을 알고 있지만 내 의견 중 어떤 부분이 그것에 관련되어 있는지 잘 모르겠다. 그리고 당신의 의견은 마이크로 커널 OS가 "무정전"프로세스에 문제가 없다는 것을 의미 하는가? 그렇지 않다면 아마도 마이크로 커널 팬이 될 때가되었을 것입니다 ... : D
Dexter

49

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

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

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

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

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

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

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

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


1
파일 시스템 잠금 버그가 원인 일 수도 있습니다 (IME).
Tobu

3
나는이 모든 것을 이해하지 못한다. "무정전 수면을 피할 수 없습니다"-무정전 수면이 단순히 상태로 존재하지 않는 방식으로 OS를 만들 수 없습니까? 그런 다음 손상에 대한 부분-프로세스 자체의 커널 모드 부분 (또는 손상으로 인한 원인)이 종료되거나 메모리에서 코드가 수정되어 반환 할 수 없습니까? Linux조차도 그렇게하기 어려운 이유가 무엇인지 설명하십시오. (이 문제는 Windows에만 존재한다고 생각했습니다)
Dexter

내가 생각할 수있는 유일한 경우는 (안전하게) 해당 프로세스를 죽이는 것을 불가능 하게 만드는 것입니다 ( 단단히 어려운 것은 아니지만) 하드웨어 자체가 손상을 일으킬 수있는 경우입니다. 하드웨어를 제어 할 수 없습니다. 커널 은 할 수 있습니다 . 그러나 하드웨어에서 데이터를 가져 와서 메모리를 수정하는 것은 커널입니다 (따라서 프로세스가 사용자 모드로 돌아 가기 전에 해제해서는 안되며 손상이 발생할 수있는 이유). 메모리에서 커널 코드를 변경하면 더 이상 문제가 없습니다.
덱스터

@Dexter는 커널이 단일 멀티 스레드 프로세스 인 것처럼 생각합니다. 여기서 각 프로세스의 커널 모드 부분은 커널 내의 스레드입니다. 다중 스레드 프로그램에서 단일 스레드를 종료하는 것만 큼 좋지 않은 제안이 있습니다. 매달려 잠금, 임시로 수정 된 데이터 구조 또는 수정되는 중간 등이 남아있을 수 있습니다.
CesarB

@CesarB 글쎄, 당신은 스레드를 죽이는 것에 대해 옳습니다 ...하지만 "주"스레드 (OS 커널이고 다른 스레드는 드라이버가 될 것입니다)가 어떻게 든 처리 할 수 ​​없습니까? "수정되는 중간에"이러한 구조는 정말 어려운 문제인 것 같습니다 ... 아마도 우리는 무정전 프로세스가 불가능한 OS를 절대 보지 못할 것입니다 :(
Dexter

23

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

이걸 고려하세요:

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

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

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

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


1
결국 실패하면 작업은 일반적으로 SIGBUS 또는 무언가를 얻습니다. 잠깐, 커널이 "무정전"프로세스를 종료 할 때 I / O 조작이 실패했다고 TELLS 할 수 없습니까? 그러면 프로세스가 사용자 모드로 돌아가서 사라 졌습니까? 이러한 'D'상태 프로세스를 안전하게 종료하는 방법이 있어야합니다. 쉽지 않은 것 같아서 Windows 나 Linux 모두 아직 그런 가능성이 없습니다. 다른 한편으로, 나는 적어도 안전하지 않은 프로세스를 죽일 수 있기를 원합니다. 시스템 충돌 가능성 등은 상관 없습니다.
Dexter

@Dexter 흠, 나는 Windows 에서이 문제를 경험 한 적이 없습니다. 그것을 재현하는 방법은 무엇입니까? 적어도이 게시물 에 따르면 모든 I / O 요청은 Windows에서 중단 될 수 있습니다.
Ruslan

1

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


-3

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

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


프로세스가 종료되는 것과 같은 방식으로 드라이버를 강제로 언로드 할 수 없습니까? 커널 모드는 사용자 모드보다 더 많은 권한을 가지고 있지만 운영 체제 자체보다 더 많은 권한을 가질 수는 없습니다. 커널 모드에서 실행되는 모든 것은 항상 커널 모드에서 실행되는 다른 것을 조작 할 수 있습니다. 제어는 없습니다.
Dexter
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.