Rust에서 비동기 IO를 구현하는 것에 대한 이 이야기 를 보고 있었고 Carl은 두 가지 잠재적 모델을 언급했습니다. 준비와 완성.
준비 모델 :
- 커널에게 소켓에서 읽고 싶다고 말하십시오.
- 잠시 다른 일을하세요…
- 커널은 소켓이 준비되면 알려줍니다
- 당신은 읽습니다 (버퍼 채우기)
- 필요한 것은 무엇이든 해
- 버퍼를 비 웁니다 (Rust에서 자동으로 발생)
완성 모델 :
- 커널이 채울 버퍼를 할당합니다
- 잠시 다른 일을하세요…
- 커널은 버퍼가 채워 졌을 때 알려줍니다
- 데이터에 필요한 모든 것을 수행
- 버퍼 해제
준비 모델을 사용하는 Carl의 예에서는 준비된 소켓을 채우고 전역 버퍼를 해제하여 메모리를 훨씬 적게 사용하는 것처럼 보일 수 있습니다 .
이제 내 가정 :
소켓이 "준비"되었다고 말할 때 (커널 공간에서) 후드 아래에 데이터가 이미 존재합니다. 네트워크를 통해 (또는 어디서나) 소켓에 들어 왔으며 OS가 데이터를 보유하고 있습니다.
메모리 준비가 마술처럼 준비 모델에서 일어나지 않는 것처럼 보이지 않습니다. OS가 당신에게서 그것을 추상화하고 있다는 것입니다. Completion 모델에서 OS는 데이터가 실제로 유입되기 전에 메모리를 할당하도록 요구하고 있으며 무슨 일이 일어나고 있는지 분명합니다.
준비 모델의 수정 된 버전은 다음과 같습니다.
- 커널에게 소켓에서 읽고 싶다고 말하십시오.
- 잠시 다른 일을하세요…
- 수정 : OS로 데이터가 들어옴 (커널 메모리의 일부)
- 커널은 소켓이 준비되었다고 알려줍니다
- 읽습니다 (위의 커널 버퍼와 별도로 다른 버퍼를 채 웁니다 (또는 포인터를 얻습니까?)).
- 필요한 것은 무엇이든 해
- 버퍼를 비 웁니다 (Rust에서 자동으로 발생)
/ 내 가정
사용자 공간 프로그램을 작게 유지하고 싶지만 실제로 여기서 일어나는 일에 대한 설명을 원했습니다. 하나의 모델이 본질적으로 더 적은 메모리를 사용하거나 더 높은 수준의 동시 IO를 지원한다는 것을 알지 못합니다. 나는 이것에 대한 생각과 더 깊은 설명을 듣고 싶습니다.