IO 스케줄러와 CPU 스케줄러의 개념이 혼란스럽습니다. 다음은 내가 이해한 것입니다.
- Linux는 기본적으로 CFS 스케줄러 + nice 값을 사용하여 프로세스를 예약합니다.
- 각 프로세스에는 IO 대기열이 있습니다.
- IO 스케줄러 커널 스레드가 있습니다.
- IO 스케줄러는 파일 수준이 아닌 블록 수준에 있습니다.
- IO 스케줄러는 파일 시스템의 모듈입니다.
질문:
IO 스케줄러와 CPU 스케줄러의 관계는 무엇입니까? 개념적으로는 CPU 스케줄러가 IO 스케줄러보다 나은 것 같습니다. CPU 스케줄링이 먼저 발생합니다. IO 스케줄러 자체는 스레드이며 CPU 스케줄링을 따릅니다.
인위적인 시나리오는 다음과 같습니다.
1단계: CPU 스케줄러는 실행을 위해 프로세스 P1을 선택합니다.
2단계: P1은 IO 요청을 자체 IO 큐에 넣습니다.
3단계 이상: CPU 스케줄러는 실행할 다른 스레드를 선택합니다. (P1을 제외한 프로세스에는 IO가 없다고 가정)
....(잠시 후)
n단계: CPU 스케줄러는 실행할 IO 스케줄러 스레드를 선택합니다.
n+1 단계: IO 스케줄러 스레드는 대기 중인 IO 요청이 있음을 P1에 "알리고" 이러한 요청을 디스크로 보냅니다.
내 이해와 시나리오가 의미가 있습니까?
답변1
IO 스케줄러부터 시작해 보겠습니다. 각 블록 장치에는 IO 스케줄러가 있습니다. 그 역할은 장치의 대기열에 쌓이는 요청을 예약(정렬)하는 것입니다. Linux 커널은 현재 deadline
, noop
및 의 세 가지 알고리즘을 제공합니다 cfq
. cfq
설명서에 따르면 기본값은 다음과 같습니다.
CFQ I/O 스케줄러는 시스템의 모든 프로세스에 대역폭을 균등하게 분배하려고 시도합니다. 데스크탑 및 서버 시스템에 적합한 공정하고 지연 시간이 짧은 작업 환경을 제공해야 합니다.
scheduler
블록 장치에 해당하는 파일을 통해 어떤 스케줄러가 어떤 장치를 관리하는지 구성할 수 있습니다 /sys/
(다음 명령을 실행하여 찾을 수 있습니다: ) find /sys | grep queue/scheduler
.
이 짧은 설명에서는 이것이 프로세스를 살펴보는 cfq
유일한 스케줄러라는 점을 설명하지 않습니다 . 프로세스에 할당할 수 있는 설정이며 알고리즘은 다른 요청을 선택하기 전에 이를 고려합니다. 유틸리티를 통해 설정할 수 있습니다 .ioprio
ioprio
ioprio
ionice
그 다음에는 작업 스케줄러가 있습니다. 그 역할은 프로세스 간에 CPU를 분배하는 것입니다.달릴 준비가 됐어. 이는 특정 프로세스의 우선순위, 클래스, 우수성뿐만 아니라 프로세스가 실행된 기간 및 기타 휴리스틱과 같은 요소를 고려합니다.
이제 귀하의 질문에 대답하려면 다음을 수행하십시오.
IO 스케줄러와 CPU 스케줄러의 관계는 무엇입니까?
이름 외에는 아무것도 없습니다. 그들은 다양한 공유 리소스를 준비합니다. 첫 번째 명령은 디스크에 요청을 보내고, 두 번째 명령은 CPU에 대한 "요청"(프로세스를 실행하기 위해 CPU 시간을 요청하는 것으로 생각할 수 있음)을 예약합니다.
CPU 스케줄링이 먼저 발생합니다. IO 스케줄러 자체는 스레드이며 CPU 스케줄링을 따릅니다.
IO 스케줄러 알고리즘이 요청을 대기 중인 프로세스에 의해 실행되는 것처럼 발생하지 않습니다. 이를 이해하는 좋은 방법은 elv_add_request()
해당 경로에서 발생하는 충돌을 살펴보는 것입니다.예를 들어:
[...]
[<c027fac4>] error_code+0x74/0x7c
[<c019ed65>] elv_next_request+0x6b/0x116
[<e08335db>] scsi_request_fn+0x5e/0x26d [scsi_mod]
[<c019ee6a>] elv_insert+0x5a/0x134
[<c019efc1>] __elv_add_request+0x7d/0x82
[<c019f0ab>] elv_add_request+0x16/0x1d
[<e0e8d2ed>] pkt_generic_packet+0x107/0x133 [pktcdvd]
[<e0e8d772>] pkt_get_disc_info+0x42/0x7b [pktcdvd]
[<e0e8eae3>] pkt_open+0xbf/0xc56 [pktcdvd]
[<c0168078>] do_open+0x7e/0x246
[<c01683df>] blkdev_open+0x28/0x51
[<c014a057>] __dentry_open+0xb5/0x160
[<c014a183>] nameidata_to_filp+0x27/0x37
[<c014a1c6>] do_filp_open+0x33/0x3b
[<c014a211>] do_sys_open+0x43/0xc7
[<c014a2cd>] sys_open+0x1c/0x1e
[<c0102b82>] sysenter_past_esp+0x5f/0x85
프로세스가 어떻게 커널에 들어가고 궁극적으로 리프트( ) elv
알고리즘과 관련된 open()을 호출하는지 주목하세요.