POSIX AIO 시설을 다양한 세부 사항으로 설명하는 페이지가 웹에 흩어져 있습니다. 그들 중 누구도 끔찍하게 최근의 것이 아닙니다. 정확히 무엇을 설명하고 있는지 명확하지 않습니다. 예를 들어 여기에있는 Linux 커널 비동기 I / O 지원을위한 “공식”(?) 웹 사이트에서는 소켓이 작동하지 않는다고 말하지만 Ubuntu 8.04.1 워크 스테이션의 “aio.h”매뉴얼 페이지는 모두 다음을 암시하는 것 같습니다. 임의의 파일 설명자에 대해 작동합니다. 그런 다음 더 적은 문서로 라이브러리 계층에서 작동하는 것으로 보이는 또 다른 프로젝트가 있습니다.
알고 싶습니다 :
- POSIX AIO의 목적은 무엇입니까? 내가 찾을 수있는 구현의 가장 명백한 예가 소켓을 지원하지 않는다는 것을 감안할 때 모든 것이 이상하게 보입니다. 비동기 디스크 I / O 전용입니까? 그렇다면 왜 하이퍼 일반 API입니까? 그렇지 않다면 왜 디스크 I / O가 가장 먼저 공격을 받았습니까?
- 내가 볼 수있는 완전한 POSIX AIO 프로그램의 예는 어디에 있습니까 ?
- 실제로 실제로 사용하는 사람이 있습니까?
- POSIX AIO를 지원하는 플랫폼은 무엇입니까? 그들은 어떤 부분을 지원합니까?
<aio.h>
약속 된 것처럼 보이는 “모든 FD에 대한 모든 I / O”를 실제로 지원하는 사람이 있습니까?
제가 사용할 수있는 다른 멀티플렉싱 메커니즘은 완벽하게 훌륭하지만 주변에 떠 다니는 임의의 정보 조각이 저를 궁금하게 만들었습니다.
답변
POSIX 네트워크 서버를 작성하는 모든 사람이 이벤트 기반 비 차단 방식을 사용하기 때문에 네트워크 I / O는 AIO의 우선 순위가 아닙니다. 구식 Java “수십억 개의 차단 스레드”접근 방식은 끔찍합니다.
디스크 쓰기 I / O는 이미 버퍼링되어 있으며 posix_fadvise와 같은 함수를 사용하여 디스크 읽기 I / O를 버퍼로 프리 페치 할 수 있습니다. 따라서 버퍼링되지 않은 직접 디스크 I / O가 AIO의 유일한 유용한 용도로 남습니다.
버퍼링되지 않은 직접 I / O는 트랜잭션 데이터베이스에만 실제로 유용하며 이들은 자체 스레드 또는 프로세스를 작성하여 디스크 I / O를 관리하는 경향이 있습니다.
따라서 결국 POSIX AIO는 유용한 목적을 제공 하지 않는 위치에 있습니다. 그것을 사용하지 마십시오.
답변
소켓 I / O를 효율적으로 수행하는 것은 kqueue, epoll, IO 완료 포트 등으로 해결되었습니다. 비동기 파일 I / O를 수행하는 것은 일종의 후발입니다 (Windows의 중첩 된 I / O 및 posix AIO에 대한 solaris 초기 지원과는 별개).
소켓 I / O를 수행하려는 경우 위의 메커니즘 중 하나를 사용하는 것이 좋습니다.
따라서 AIO의 주요 목적은 비동기 디스크 I / O 문제를 해결하는 것입니다. 이것이 Mac OS X이 소켓이 아닌 일반 파일에 대해서만 AIO를 지원하는 이유 일 가능성이 큽니다 (kqueue가 더 나은 방법이기 때문입니다).
쓰기 작업은 일반적으로 커널에 의해 캐시되고 나중에 플러시됩니다. 예를 들어 드라이브의 읽기 헤드가 블록이 기록 될 위치를 지나가는 경우입니다.
그러나 읽기 작업의 경우 커널에서 읽기 우선 순위를 지정하고 순서를 지정하려면 AIO가 실제로 유일한 옵션입니다. 커널이 (이론적으로) 어떤 사용자 수준 응용 프로그램보다 더 잘 할 수있는 이유는 다음과 같습니다.
- 커널은 응용 프로그램 디스크 작업뿐만 아니라 모든 디스크 I / O를보고 글로벌 수준에서 주문할 수 있습니다.
- 커널은 디스크 읽기 헤드가 어디에 있는지 알고 있으며, 헤드를 최단 거리로 이동하기 위해 최적의 순서로 전달하는 읽기 작업을 선택할 수 있습니다.
- 커널은 원시 명령 대기열 을 활용 하여 읽기 작업을 더욱 최적화 할 수 있습니다.
- readv ()보다 lio_listio ()를 사용하여 시스템 호출 당 더 많은 읽기 작업을 수행 할 수 있습니다. 특히 읽기가 (논리적으로) 연속적이지 않은 경우 시스템 호출 오버 헤드를 약간 절약 할 수 있습니다.
- 읽기 또는 쓰기 호출에서 차단할 추가 스레드가 필요하지 않기 때문에 AIO를 사용하면 프로그램이 약간 더 간단해질 수 있습니다.
즉, posix AIO에는 매우 어색한 인터페이스가 있습니다. 예를 들면 다음과 같습니다.
- 유일하게 효율적이고 잘 지원되는 이벤트 콜백 수단은 신호를 통한 것이므로 프로세스 전역 신호 네임 스페이스의 신호 번호를 사용하기 때문에 라이브러리에서 사용하기가 어렵습니다. OS가 실시간 신호를 지원하지 않는다면, 어떤 요청이 실제로 완료되었는지 확인하기 위해 모든 미해결 요청을 반복해야 함을 의미합니다 (예 : Linux가 아닌 Mac OS X의 경우). 다중 스레드 환경에서 신호를 포착하면 몇 가지 까다로운 제한이 발생합니다. 일반적으로 시그널 핸들러 내부의 이벤트에 반응 할 수 없지만 시그널을 발생 시키거나 파이프에 쓰거나 signalfd () (리눅스에서)를 사용해야합니다.
- lio_suspend ()는 select ()와 동일한 문제를 가지고 있으며 작업 수에 따라 확장되지 않습니다.
- 구현 된대로 lio_listio ()는 전달할 수있는 작업의 수가 상당히 제한되어 있으며 이식 가능한 방식으로이 제한을 찾는 것은 사소한 일이 아닙니다. sysconf (_SC_AIO_LISTIO_MAX)를 호출해야합니다.이 경우 실패 할 수 있습니다.이 경우 반드시 정의되지 않은 AIO_LISTIO_MAX 정의를 사용할 수 있지만 지원이 보장되는 것으로 정의 된 2를 사용할 수 있습니다.
posix AIO를 사용하는 실제 응용 프로그램의 경우 지원을 도입 할 때 성능 측정을 게시 한 lighttpd (lighty)를 살펴볼 수 있습니다 .
대부분의 posix 플랫폼은 현재 posix AIO를 지원합니다 (Linux, BSD, Solaris, AIX, tru64). Windows는 겹친 파일 I / O를 통해이를 지원합니다. 내 이해는 Solaris, Windows 및 Linux만이 진정으로 비동기를 지원한다는 것입니다. 다른 OS는 비동기를 에뮬레이트하는 반면 파일 I / O는 드라이버까지 내려갑니다. 커널 스레드가있는 I / O. Linux는 예외입니다. glibc의 posix AIO 구현은 사용자 수준 스레드를 사용하여 비동기 작업을 에뮬레이트하는 반면 기본 비동기 I / O 인터페이스 (io_submit () 등)는 드라이버가 지원한다고 가정 할 때 완전히 비동기식입니다. .
나는 모든 fd에 대해 posix AIO를 지원하지 않지만 일반 파일로 제한하는 것이 OS 사이에서 상당히 일반적이라고 생각합니다.
답변
libtorrent 개발자가 이에 대한 보고서를 제공합니다. http://blog.libtorrent.org/2012/10/asynchronous-disk-io/
답변
aio_write가 있습니다-glibc에서 구현되었습니다. aio_read 또는 aio_write 함수의 첫 번째 호출은 여러 사용자 모드 스레드, aio_write 또는 aio_read 포스트 요청을 해당 스레드에 생성하고 스레드는 pread / pwrite를 수행하며 완료되면 응답이 차단 된 호출 스레드에 다시 게시됩니다.
Ther은 또한 ‘실제’aio입니다-커널 수준에서 지원합니다 (libaio 필요, io_submit 호출 http://linux.die.net/man/2/io_submit 참조 ). 이를 위해 O_DIRECT도 필요합니다 (모든 파일 시스템에서 지원되지 않을 수도 있지만 주요 파일 시스템에서 지원함).
여기를 보아라:
http://lse.sourceforge.net/io/aio.html