Linux 프로세스 상태
Linux에서 디스크에서 블록을 읽어야 할 때 프로세스 상태는 어떻게됩니까? 차단 되었습니까? 그렇다면 다른 프로세스를 어떻게 선택합니까?
파일 디스크립터 리턴을 기다리 read()
거나 오가는 동안 write()
프로세스는 "D"또는 "디스크 슬립"으로 알려진 특별한 종류의 슬립 상태가됩니다. 이러한 상태에서는 프로세스를 종료하거나 중단 할 수 없기 때문에 이것은 특별합니다. ioctl ()에서 리턴을 기다리는 프로세스도 이런 방식으로 휴면 상태가됩니다.
이에 대한 예외는 파일 (예 : 터미널 또는 기타 문자 장치)이 O_NONBLOCK
모드에서 열리고 장치 (예 : 모뎀)가 초기화하는 데 시간이 필요하다고 가정 할 때 전달되는 경우입니다. 그러나 질문에 블록 장치를 표시했습니다. 또한 ioctl()
비 차단 모드에서 열린 fd에서 차단할 가능성 이있는를 시도한 적이 없습니다 (적어도 고의적으로는).
다른 프로세스를 선택하는 방법은 전적으로 사용중인 스케줄러와 해당 스케줄러 내에서 가중치를 수정하기 위해 다른 프로세스가 수행 한 작업에 따라 다릅니다.
특정 상황에서 일부 사용자 공간 프로그램은 재부팅 될 때까지이 상태를 영원히 유지하는 것으로 알려져 있습니다. 이들은 일반적으로 다른 "좀비"와 함께 그룹화되지만 기술적으로 소멸되지 않았기 때문에 용어는 정확하지 않습니다.
프로세스가 디스크에서 데이터를 가져와야하는 경우 작업을 완료하는 데 오랜 시간이 걸릴 수 있으므로 CPU에서 실행을 효과적으로 중지하여 다른 프로세스를 실행할 수 있습니다. 디스크 검색 시간은 최소 5ms가 일반적이며 5ms는 1,000 만입니다. CPU 사이클, 프로그램의 관점에서 본 영원!
프로그래머의 관점에서 ( "사용자 공간에서"라고도 함)이를 차단 시스템 호출이라고 합니다. 당신이 호출하는 경우 write(2)
(같은 이름의 시스템 호출 주위에 얇은 libc의 래퍼 인), 프로세스는 정확히 그 경계에서 멈추지 않는다; 커널에서 시스템 호출 코드를 계속 실행합니다. 대부분의 경우 특정 디스크 컨트롤러 드라이버 (파일 이름 → 파일 시스템 / VFS → 블록 장치 → 장치 드라이버)까지 이동합니다. 여기서 디스크의 블록을 가져 오는 명령이 적절한 하드웨어에 제출됩니다. 대부분의 경우 빠른 작동.
그런 다음 프로세스가 절전 상태가됩니다 (커널 공간에서 차단 을 절전 이라고합니다. 커널 관점에서 '차단'되는 것은 없습니다). 하드웨어가 마침내 적절한 데이터를 가져 오면 깨어 나면 프로세스가 실행 가능한 것으로 표시되고 예약됩니다. 결국 스케줄러는 프로세스를 실행합니다.
마지막으로 사용자 공간에서 차단 시스템 호출 이 적절한 상태와 데이터로 반환되고 프로그램 흐름이 계속됩니다.
대부분의 I / O 시스템 호출을 호출 할 수 있습니다 비 차단 모드 (참조 O_NONBLOCK
로 open(2)
하고 fcntl(2)
). 이 경우 시스템 호출이 즉시 반환되고 디스크 작업 제출 만보고합니다. 프로그래머는 작업이 성공적으로 완료되었는지 여부를 나중에 명시 적으로 확인하고 그 결과를 가져와야합니다 (예 :) select(2)
. 이를 비동기 또는 이벤트 기반 프로그래밍이라고합니다.
여기에서 D 상태 ( TASK_UNINTERRUPTIBLE
Linux 상태 이름으로 호출 됨) 를 언급하는 대부분의 답변 은 올바르지 않습니다. D의 상태는 그 코드 경로가 커널 공간 코드 경로에 트리거되는 특별한 절전 모드 중단 할 수없는 이 매우 만 차단 것이라는 기대와 (이 프로그램에 너무 복잡하기 때문)을, 짧은 시간. 나는 대부분의 "D 상태"가 실제로 보이지 않는다고 믿습니다. 수명이 매우 짧고 '상단'과 같은 샘플링 도구로 관찰 할 수 없습니다.
몇 가지 상황에서 D 상태에서 종료 할 수없는 프로세스가 발생할 수 있습니다. NFS는 그 점으로 유명하며 여러 번 접했습니다. 항상 로컬 디스크에 도달하고 빠른 오류 감지 (SATA에서는 오류 시간 초과가 약 100ms)라고 가정하는 일부 VFS 코드 경로와 실제로 네트워크에서 데이터를 가져 오는 NFS간에 의미 론적 충돌이 있다고 생각합니다. 복원력이 더 높고 복구 속도가 느립니다 (300 초의 TCP 시간 초과가 일반적 임). 상태 와 함께 Linux 2.6.25에 도입 된 멋진 솔루션에 대해이 기사 를 읽으십시오 TASK_KILLABLE
. 이 시대 이전에는 커널 스레드에 SIGKILL을 전송하여 NFS 프로세스 클라이언트에 실제로 신호를 보낼 수있는 해킹이 rpciod
있었지만 그 추악한 트릭은 잊어 버렸습니다.…
I / O를 수행하는 프로세스는 D 상태 (무정전 절전)에 놓이게되며 , CPU가 프로그램 실행으로 돌아가도록 지시하는 하드웨어 인터럽트가있을 때까지 CPU를 해제합니다. man ps
다른 프로세스 상태는를 참조하십시오 .
커널에 따라 실행할 준비가 된 프로세스의 실행 대기열을 추적 하는 프로세스 스케줄러 가 있습니다. 스케줄링 알고리즘과 함께 어떤 프로세스를 어떤 CPU에 할당할지 커널에 알려줍니다. 고려해야 할 커널 프로세스와 사용자 프로세스가 있습니다. 각 프로세스에는 사용할 수있는 CPU 시간 청크 인 시간 분할이 할당됩니다. 프로세스가 모든 타임 슬라이스를 사용하면 만료 된 것으로 표시되고 스케줄링 알고리즘에서 더 낮은 우선 순위가 부여됩니다.
에서 2.6 커널 하는이없는 O (1) 시간 복잡도 스케줄러 실행까지 얼마나 많은 프로세스가 일정 시간에 CPU를 할당합니다 그래서 상관없이. 2.6은 선점을 도입하고 CPU 부하 분산이 쉬운 알고리즘이 아니기 때문에 더 복잡합니다. 어쨌든 효율적이며 I / O를 기다리는 동안 CPU는 유휴 상태로 유지되지 않습니다.
다른 사람들이 이미 설명했듯이 "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
파일 시스템이 바쁘기 때문에 마운트 해제되지 않았지만 관련 프로세스가 깨어나서 재부팅하지 않고도 문제를 해결할 수있었습니다.
Assuming your process is a single thread, and that you're using blocking I/O, your process will block waiting for the I/O to complete. The kernel will pick another process to run in the meantime based on niceness, priority, last run time, etc. If there are no other runnable processes, the kernel won't run any; instead, it'll tell the hardware the machine is idle (which will result in lower power consumption).
Processes that are waiting for I/O to complete typically show up in state D in, e.g., ps
and top
.
Yes, the task gets blocked in the read() system call. Another task which is ready runs, or if no other tasks are ready, the idle task (for that CPU) runs.
A normal, blocking disc read causes the task to enter the "D" state (as others have noted). Such tasks contribute to the load average, even though they're not consuming the CPU.
Some other types of IO, especially ttys and network, do not behave quite the same - the process ends up in "S" state and can be interrupted and doesn't count against the load average.
Yes, tasks waiting for IO are blocked, and other tasks get executed. Selecting the next task is done by the Linux scheduler.
Generally the process will block. If the read operation is on a file descriptor marked as non-blocking or if the process is using asynchronous IO it won't block. Also if the process has other threads that aren't blocked they can continue running.
The decision as to which process runs next is up to the scheduler in the kernel.
참고URL : https://stackoverflow.com/questions/1475683/linux-process-states
'programing tip' 카테고리의 다른 글
CentOS 7.2에서 yum으로 gcc 5.3을 설치하는 방법은 무엇입니까? (0) | 2020.09.18 |
---|---|
구조체가 인터페이스를 구현하는 것이 안전합니까? (0) | 2020.09.18 |
GCC 및 Clang 파서는 실제로 손으로 작성됩니까? (0) | 2020.09.18 |
require (vendor / autoload.php) : 스트림을 열지 못했습니다. (0) | 2020.09.18 |
Angular 2의 특정 경로에 대해 RouteReuseStrategy shouldDetach를 구현하는 방법 (0) | 2020.09.18 |