Linux 프로세스 상태


90

Linux에서 디스크에서 블록을 읽어야 할 때 프로세스 상태는 어떻게됩니까? 차단 되었습니까? 그렇다면 다른 프로세스를 어떻게 실행하도록 선택합니까?

답변:


87

파일 디스크립터 리턴을 기다리 read()거나받는 동안 write()프로세스는 "D"또는 "디스크 슬립"으로 알려진 특수한 종류의 슬립 상태에 놓이게됩니다. 이러한 상태에서는 프로세스를 종료하거나 중단 할 수 없기 때문에 이것은 특별합니다. ioctl ()에서 리턴을 기다리는 프로세스도 이런 방식으로 휴면 상태가됩니다.

이에 대한 예외는 파일 (예 : 터미널 또는 기타 문자 장치)이 O_NONBLOCK모드에서 열리고 장치 (예 : 모뎀)가 초기화하는 데 시간이 필요하다고 가정 할 때 전달되는 경우입니다. 그러나 질문에 블록 장치를 표시했습니다. 또한 ioctl()비 차단 모드에서 열린 fd에서 차단할 가능성 이있는를 시도한 적이 없습니다 (적어도 고의적으로).

다른 프로세스를 선택하는 방법은 사용중인 스케줄러와 해당 스케줄러 내에서 가중치를 수정하기 위해 다른 프로세스가 수행 한 작업에 따라 전적으로 달라집니다.

특정 상황에서 일부 사용자 공간 프로그램은 재부팅 될 때까지이 상태를 영원히 유지하는 것으로 알려져 있습니다. 이들은 일반적으로 다른 "좀비"와 함께 그룹화되지만 기술적으로 소멸되지 않았기 때문에 용어는 정확하지 않습니다.


1
"ioctl ()에서 리턴을 기다리는 프로세스도 이런 방식으로 휴면 상태가됩니다." 방금 차단 IOCTL을 기다리는 사용자 공간 프로세스를 죽였으므로 이것은 사실이 아닙니다. 나는 missunderstanding있어하지 않는 한
Hamzahfrq

그러한 테스트 시간을 맞추는 것은 엄청나게 어려울 것 입니다. 중단 불가능한 프로세스는 죽일 수 없습니다. 당신이 그것을 죽일 수 있었다면 그것은 단순히 차단하는 것입니다 (커널은 ioctl의 어떤 부분도 중간에 있지 않았고, 당신이 전달한 위치의 사용자 공간에 대응하는 응답을 복사했습니다 (또는 적어도 복사 중)). 이 글이 쓰여진 2009 년 이후 리눅스도 많이 바뀌 었습니다 . 현상은 예전처럼 훨씬 덜 관찰됩니다.
Tim Post

133

프로세스가 디스크에서 데이터를 가져와야하는 경우 작업을 완료하는 데 오랜 시간이 걸릴 수 있으므로 CPU에서 실행을 효과적으로 중지하여 다른 프로세스를 실행할 수 있습니다. 디스크 검색 시간은 최소 5ms가 일반적이며 5ms는 1,000 만입니다. CPU 사이클, 프로그램의 관점에서 본 영원!

프로그래머 관점 ( "사용자 공간"이라고도 함)에서이를 차단 시스템 호출이라고 합니다. 당신이 호출하는 경우 write(2)(같은 이름의 시스템 호출 주위에 얇은 libc의 래퍼 인), 프로세스는 정확히 그 경계에서 멈추지 않는다; 커널에서 시스템 호출 코드를 계속 실행합니다. 대부분의 경우 특정 디스크 컨트롤러 드라이버 (파일 이름 → 파일 시스템 / VFS → 블록 장치 → 장치 드라이버)까지 이동합니다. 여기서 디스크의 블록을 가져 오는 명령은 적절한 하드웨어에 제출됩니다. 대부분의 경우 빠른 작동.

그런 다음 프로세스가 절전 상태가됩니다 (커널 공간에서 차단 을 절전 이라고합니다. 커널 관점에서 '차단'되는 것은 없습니다). 하드웨어가 마침내 적절한 데이터를 가져 오면 깨어 나면 프로세스가 실행 가능한 것으로 표시되고 예약됩니다. 결국 스케줄러는 프로세스를 실행합니다.

마지막으로 사용자 공간에서 차단 시스템 호출 이 적절한 상태와 데이터로 반환되고 프로그램 흐름이 계속됩니다.

대부분의 I / O 시스템 호출을 호출 할 수 있습니다 비 차단 모드 (참조 O_NONBLOCKopen(2)하고 fcntl(2)). 이 경우 시스템 호출이 즉시 반환되고 디스크 작업 제출 만보고합니다. 프로그래머는 작업이 성공적으로 완료되었는지 여부를 나중에 명시 적으로 확인하고 그 결과를 가져와야합니다 (예 :) select(2). 이를 비동기 또는 이벤트 기반 프로그래밍이라고합니다.

여기에서 D 상태 ( TASK_UNINTERRUPTIBLELinux 상태 이름으로 호출 됨) 를 언급하는 대부분의 답변 은 올바르지 않습니다. D의 상태는 그 코드 경로가 커널 공간 코드 경로에 트리거되는 특별한 절전 모드 중단 할 수없는 이 매우 만 차단 것이라는 기대와 (이 프로그램에 너무 복잡하기 때문)을, 짧은 시간. 나는 대부분의 "D 상태"가 실제로 보이지 않는다고 믿습니다. 수명이 매우 짧고 '상단'과 같은 샘플링 도구로 관찰 할 수 없습니다.

몇 가지 상황에서 D 상태에서 종료 할 수없는 프로세스가 발생할 수 있습니다. NFS는 그 점으로 유명하며 여러 번 접했습니다. 항상 로컬 디스크에 도달하고 빠른 오류 감지 (SATA에서는 오류 시간 초과가 약 100ms 정도 임)에 도달한다고 가정하는 일부 VFS 코드 경로와 실제로 네트워크에서 데이터를 가져 오는 NFS간에 의미 론적 충돌이 있다고 생각합니다. 복원력이 더 높고 복구 속도가 느립니다 (300 초의 TCP 제한 시간이 일반적 임). 상태 와 함께 Linux 2.6.25에 도입 된 멋진 솔루션에 대해이 기사 를 읽으십시오 TASK_KILLABLE. 이 시대 이전에는 커널 스레드에 SIGKILL을 전송하여 NFS 프로세스 클라이언트에 신호를 보낼 수있는 해킹이 rpciod있었지만 그 추악한 트릭은 잊어 버렸습니다.…


2
자세한 답변은 +1이지만이 스레드는 거의 2 년 동안 답변을 받아 왔습니다. 최근 질문에 대한 도움을 원하시면 "질문"링크를 누르십시오. Stack Overflow에 오신 것을 환영합니다. 기여해 주셔서 감사합니다!
GargantuChet 2011

20
이 답변은 NFS를 언급하는 유일한 답변이며 일부 환경에서는 D 상태의 프로세스에 대한 가장 일반적인 설명입니다. +1.
핑코

14
아주 좋은 대답입니다. 감사합니다. 또한 스왑 아웃 된 페이지를 기다리는 동안 프로세스는 D 상태가되므로 스 래싱 프로세스는 오랫동안 D 상태에있게됩니다.
cha0site

@zerodeux 좋은 대답이지만 스키마 (파일 이름-> 파일 시스템 / VFS-> 블록 장치-> 장치 드라이버)는 (파일 이름-> VFS-> 파일 시스템 (ext3)-> 블록 장치-> 장치 드라이버)
c4f4t0r

1
커널에서 스핀 락 (디스크 입출력과 관련이있을 수도 있고 아닐 수도 있음)을 기다리는 데 소요 된 시간이 모두 D 상태로보고되었다고 가정하는 것이 안전 /proc/stat할까요?
심지

8

I / O를 수행하는 프로세스는 D 상태 (무중단 절전)에 놓이게되며 , CPU가 프로그램 실행으로 돌아가도록 지시하는 하드웨어 인터럽트가있을 때까지 CPU를 해제합니다. man ps다른 프로세스 상태는를 참조하십시오 .

커널에 따라 실행할 준비가 된 프로세스의 실행 대기열을 추적 하는 프로세스 스케줄러 가 있습니다. 스케줄링 알고리즘과 함께 어떤 프로세스를 어떤 CPU에 할당할지 커널에 알려줍니다. 고려해야 할 커널 프로세스와 사용자 프로세스가 있습니다. 각 프로세스에는 사용이 허용 된 CPU 시간 청크 인 타임 슬라이스가 할당됩니다. 프로세스가 모든 타임 슬라이스를 사용하면 만료 된 것으로 표시되고 스케줄링 알고리즘에서 더 낮은 우선 순위가 부여됩니다.

에서 2.6 커널 하는이없는 O (1) 시간 복잡도 스케줄러 실행까지 얼마나 많은 프로세스가 일정 시간에 CPU를 할당합니다 그래서 상관없이. 2.6은 선점을 도입하고 CPU 부하 분산이 쉬운 알고리즘이 아니기 때문에 더 복잡합니다. 어쨌든 효율적이며 I / O를 기다리는 동안 CPU는 유휴 상태로 유지되지 않습니다.


3

다른 사람들이 이미 설명했듯이 "D"상태 (무정전 절전)의 프로세스는 ps 프로세스의 중단을 담당합니다. 나에게는 RedHat 6.x 및 자동 마운트 된 NFS 홈 디렉토리에서 여러 번 발생했습니다.

D 상태의 프로세스를 나열하려면 다음 명령을 사용할 수 있습니다.

cd /proc
for i in [0-9]*;do echo -n "$i :";cat $i/status |grep ^State;done|grep D

프로세스의 현재 디렉토리 및 문제가있는 마운트 된 NFS 디스크를 확인하려면 다음 예제와 유사한 명령을 사용할 수 있습니다 (31134를 휴면 프로세스 번호로 대체).

# ls -l /proc/31134/cwd
lrwxrwxrwx 1 pippo users 0 Aug  2 16:25 /proc/31134/cwd -> /auto/pippo

-f (force) 스위치와 함께 umount 명령을 마운트 된 관련 nfs 파일 시스템에 제공하면 잠자기 프로세스를 깨울 수 있음을 발견했습니다.

umount -f /auto/pippo

파일 시스템이 바쁘기 때문에 마운트 해제되지 않았지만 관련 프로세스가 깨어나서 재부팅하지 않고도 문제를 해결할 수있었습니다.


1

프로세스가 단일 스레드이고 차단 I / O를 사용하고 있다고 가정하면 프로세스는 I / O가 완료 될 때까지 대기하는 것을 차단합니다. 커널은 niceness, 우선 순위, 마지막 실행 시간 등에 따라 그동안 실행할 다른 프로세스를 선택합니다. 실행 가능한 다른 프로세스가 없으면 커널은 실행되지 않습니다. 대신, 기계가 유휴 상태임을 하드웨어에 알려줍니다 (이로 인해 전력 소비가 낮아집니다).

I / O가 완료되기를 기다리는 프로세스는 일반적으로 상태 D로 표시됩니다 (예 : ps및) top.


전체 메모리의 약 10 %를 사용하여 여러 프로세스를 시작했습니다. 나는 그들 중 많은 사람들이 D 상태에 있음을 알았습니다. 이 특정 시스템의 느린 IO 때문입니까? 내가 9 개의 프로세스를 가지고 있다고 가정하면, 그들은 IO를 놓고 경쟁하고 있고 그들 중 다수는 D 상태에 있습니다.
Kemin Zhou

@KeminZhou CPU 속도에 비해 I / O는 매우 느립니다. 심지어 빠른 I / O도 마찬가지입니다. 단일 I / O 무거운 프로세스는 자기 디스크, 심지어 SSD를 쉽게 사용할 수 있습니다. 10 I / O 과중한 프로세스는 꽤 많이 바쁠 수 있습니다.
derobert jul.

1

예, 작업은 read () 시스템 호출에서 차단됩니다. 준비된 다른 작업이 실행되거나 다른 작업이 준비되지 않은 경우 유휴 작업 (해당 CPU에 대한)이 실행됩니다.

정상적인 디스크 읽기를 차단하면 작업이 "D"상태로 전환됩니다 (다른 사용자가 언급 한대로). 이러한 작업은 CPU를 사용하지 않더라도 평균로드에 기여합니다.

일부 다른 유형의 IO, 특히 tty 및 네트워크는 완전히 동일하게 작동하지 않습니다. 프로세스는 "S"상태로 끝나고 중단 될 수 있으며로드 평균에 포함되지 않습니다.



0

일반적으로 프로세스가 차단됩니다. 읽기 작업이 비 차단으로 표시된 파일 설명자에 있거나 프로세스가 비동기 IO를 사용하는 경우 차단되지 않습니다. 또한 프로세스에 차단되지 않은 다른 스레드가 있으면 계속 실행할 수 있습니다.

다음에 실행할 프로세스에 대한 결정 은 커널 의 스케줄러 에 달려 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.