문제

POSIX AIO 기능을 다양한 세부 정보로 설명하는 페이지가 웹에 흩어져 있습니다.그들 중 어느 것도 아주 최근의 것은 아닙니다.그들이 정확히 무엇을 설명하고 있는지는 확실하지 않습니다.예를 들어, "공식"(?) Linux 커널 비동기 I/O 지원을 위한 웹사이트는 여기를 참조하세요. 소켓이 작동하지 않는다고 나와 있지만 내 Ubuntu 8.04.1 워크스테이션의 "aio.h" 매뉴얼 페이지는 모두 임의의 파일 설명자에 대해 작동한다는 것을 암시하는 것 같습니다.그럼 거기에 라이브러리 계층에서 작동하는 것으로 보이는 또 다른 프로젝트 문서가 훨씬 적습니다.

나는 알고 싶습니다:

  • POSIX AIO의 목적은 무엇입니까?내가 찾을 수 있는 구현의 가장 확실한 예가 소켓을 지원하지 않는다는 점을 고려하면 모든 것이 이상하게 보입니다.비동기 디스크 I/O에만 해당됩니까?그렇다면 왜 초일반 API를 사용하는가?그렇지 않다면 왜 디스크 I/O가 가장 먼저 공격을 받았을까요?
  • 예가 어디에 있습니까? 완벽한 내가 볼 수 있는 POSIX AIO 프로그램은 무엇입니까?
  • 실제로 실제로 사용하는 사람이 있나요?
  • POSIX AIO를 지원하는 플랫폼은 무엇입니까?어떤 부분을 지원합니까?누구든지 "모든 FD에 대한 모든 I/O"를 실제로 지원합니까? <aio.h> 약속한 것 같은데?

내가 사용할 수 있는 다른 다중화 메커니즘은 완벽하게 훌륭하지만, 거기에 떠다니는 임의의 정보 조각이 나를 궁금하게 만들었습니다.

도움이 되었습니까?

해결책

POSIX 네트워크 서버를 작성하는 모든 사람이 이벤트 기반의 비차단 접근 방식을 사용하기 때문에 네트워크 I/O는 AIO의 우선 순위가 아닙니다.구식 Java "수십억 개의 스레드 차단" 접근 방식은 끔찍할 정도로 형편없습니다.

디스크 쓰기 I/O는 이미 버퍼링되어 있으며 디스크 읽기 I/O는 posix_fadvise와 같은 함수를 사용하여 버퍼로 미리 가져올 수 있습니다.따라서 직접적이고 버퍼링되지 않은 디스크 I/O가 AIO의 유일한 유용한 목적으로 남습니다.

버퍼링되지 않은 직접 I/O는 트랜잭션 데이터베이스에만 실제로 유용하며, 디스크 I/O를 관리하기 위해 자체 스레드나 프로세스를 작성하는 경향이 있습니다.

그래서 결국 POSIX AIO는 서비스를 제공하지 않는 위치에 있게 됩니다. 어느 유용한 목적.사용하지 마십시오.

다른 팁

소켓 I/O를 효율적으로 수행하는 것은 kqueue, epoll, IO 완료 포트 등을 통해 해결되었습니다.비동기식 파일 I/O를 수행하는 것은 일종의 후발주자입니다(Windows의 중첩 I/O 및 posix AIO에 대한 솔라리스의 초기 지원은 제외).

소켓 I/O를 수행하려는 경우 위 메커니즘 중 하나를 사용하는 것이 더 나을 것입니다.

따라서 AIO의 주요 목적은 비동기 디스크 I/O 문제를 해결하는 것입니다.이것이 Mac OS X가 소켓이 아닌 일반 파일에 대해서만 AIO를 지원하는 이유일 가능성이 높습니다(어차피 kqueue가 훨씬 더 나은 기능을 제공하기 때문입니다).

쓰기 작업은 일반적으로 커널에 의해 캐시되고 나중에 플러시됩니다.예를 들어 드라이브의 읽기 헤드가 블록이 기록될 위치를 우연히 지나가는 경우입니다.

그러나 읽기 작업의 경우 커널이 읽기 우선순위를 지정하고 순서를 지정하도록 하려면 AIO가 실제로 유일한 옵션입니다.커널이 (이론적으로) 어떤 사용자 수준 애플리케이션보다 더 나은 작업을 수행할 수 있는 이유는 다음과 같습니다.

  • 커널은 애플리케이션 디스크 작업뿐만 아니라 모든 디스크 I/O를 확인하고 전역 수준에서 주문할 수 있습니다.
  • 커널은 디스크 읽기 헤드가 어디에 있는지 알고 있으며 최적의 순서로 전달하는 읽기 작업을 선택하여 헤드를 가장 짧은 거리로 이동할 수 있습니다.
  • 커널은 다음을 활용할 수 있습니다. 네이티브 명령 대기열 읽기 작업을 더욱 최적화하기 위해
  • readv()를 사용하는 것보다 lio_listio()를 사용하여 시스템 호출당 더 많은 읽기 작업을 실행할 수 있습니다. 특히 읽기가 (논리적으로) 연속적이지 않은 경우 시스템 호출 오버헤드를 약간 절약할 수 있습니다.
  • 읽기 또는 쓰기 호출을 차단하기 위해 추가 스레드가 필요하지 않기 때문에 AIO를 사용하면 프로그램이 약간 더 단순해질 수 있습니다.

즉, posix AIO는 매우 어색한 인터페이스를 가지고 있습니다. 예를 들면 다음과 같습니다.

  • 유일하게 효율적이고 잘 지원되는 이벤트 콜백 수단은 신호를 통하는 것입니다. 이는 프로세스 전역 신호 네임스페이스의 신호 번호를 사용한다는 의미이므로 라이브러리에서 사용하기 어렵습니다.OS가 실시간 신호를 지원하지 않는 경우 이는 실제로 완료된 요청을 파악하기 위해 모든 미해결 요청을 반복해야 함을 의미합니다(예를 들어 Linux가 아닌 Mac OS X의 경우).멀티 스레드 환경에서 신호를 포착하면 몇 가지 까다로운 제한 사항이 발생합니다.일반적으로 신호 처리기 내부의 이벤트에 반응할 수 없지만 신호를 발생시키거나 파이프에 쓰거나 (Linux에서) signalfd()를 사용해야 합니다.
  • lio_suspens()에는 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만이 실제로 비동기를 지원한다는 것입니다.파일 I/O는 드라이버까지 내려가는 반면 다른 OS는 비동기를 에뮬레이트합니다.커널 스레드를 사용한 I/O.Linux는 예외입니다. glibc의 posix AIO 구현은 사용자 수준 스레드를 사용하여 비동기 작업을 에뮬레이션하는 반면, 기본 비동기 I/O 인터페이스(io_submit() 등)는 드라이버가 지원한다고 가정할 때 드라이버까지 완전히 비동기적입니다. .

나는 OS에서 어떤 fd에 대해서도 posix AIO를 지원하지 않고 일반 파일로 제한하는 것이 상당히 일반적이라고 생각합니다.

libtorrent 개발자는 이에 대한 보고서를 제공합니다: http://blog.libtorrent.org/2012/10/asynchronous-disk-io/

aio_write가 있습니다 - glibc에서 구현되었습니다.aio_read 또는 aio_write 함수의 첫 번째 호출은 여러 사용자 모드 스레드를 생성하고, aio_write 또는 aio_read는 해당 스레드에 요청을 게시하고, 스레드는 pread/pwrite를 수행하며, 완료되면 응답이 차단된 호출 스레드에 다시 게시됩니다.

또한 '실제' aio도 있습니다. 커널 수준에서 지원됩니다(이를 위해서는 libaio가 필요합니다. io_submit 호출 참조). http://linux.die.net/man/2/io_submit );이를 위해서는 O_DIRECT도 필요합니다(모든 파일 시스템에서 지원되지 않을 수도 있지만 주요 파일 시스템에서는 지원합니다)

여기를 보아라:

http://lse.sourceforge.net/io/aio.html

http://linux.die.net/man/2/io_submit

Linux에서 POSIX AIO와 libaio의 차이점은 무엇입니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top