Asynchroniczne I/O

Spis treści


Wstęp

W odróżnieniu od operacji synchronicznej, wykonanie operacji asynchronicznego wejściawyjścia (ang. Asynchronous Input/Output, w skrócie AIO), z punktu widzenia zleceniodawcy, składa się z dwóch faz:
1. zlecenia operacji,
2. pobrania informacji zwrotnej, że operacja wykonała się.

Implementacja AIO odpowiada za wykonanie zleconego odczytu (zapisu) pomiędzy fazą pierwszą a drugą oraz za przekazanie informacji o jej zakończeniu. Zlecający proces może w międzyczasie wykonywać swoje zadania i odczyt (zapis) wykona się współbieżnie z jego ścieżką wykonania. Podstawowymi zaletami operacji asynchronicznych są:

AIO jest obecnie obsługiwane przez wszystkie liczące się systemy operacyjne. Operacje asynchroniczne zostały także dodane do jądra systemu Linux, począwszy od wersji 2.5.


Kontekst

Aby wykonywać operacje asynchroniczne w Linuksie należy najpierw utworzyć dla nich kontekst
int io_setup(int maxevents, aio_context_t *ctxp)
Każda operacja wykonuje się w dokładnie jednym kontekście. W tym samym kontekście może natomiast wykonywać się wiele operacji, odnoszących się do dowolnych deskryptorów. Parametr maxevents określa ile co najwyżej zdarzeń zakończenia ma móc przechowywać tworzony kontekst. Bufor do przechowywania zdarzeń tworzony jest raz i ma stałą wielkość. Liczba zdarzeń ma wpływ na liczbę wykonujących się asynchronicznie operacji. Zlecenie nowej operacji powiedzie się tylko wtedy, gdy będzie zagwarantowane miejsce w buforze na zdarzenie jej zakończenia, w przeciwnym wypadku przy próbie zlecenia przekazany zostanie błąd [EAGAIN]. Po pomyślnym zakończeniu działania funkcji io setup identyfikator nowo utworzonego kontekstu zostanie skopiowany pod adres ctxp.


Zlecanie operacji asynchronicznego I/O

By zlecić operację asynchroniczną, należy wywołać funkcję
int io_submit(aio_context_t ctx, long nr, struct iocb *iocbs[]).
Za jej pomocą zleca się wykonanie nr operacji. Wskaźniki do ich rekordów kontrolnych znajdują się w tablicy iocbs. Funkcja przekazuje liczbę operacji, które udało się zlecić (operacje z tablicy zlecane są kolejno). W przypadku, gdy nie uda się zlecić żadnej operacji przekazywany jest kod błędu dla pierwszej z nich.


Oczekiwanie na zakończenie operacji

Funkcja
int io_getevents(aio_context_t ctx, long min_nr, long nr, struct io_event *events, struct timespec *timeout)
służy do oczekiwania na wykonanie się przynajmniej min nr spośród operacji wykonujących się w kontekście ctx. W przypadku wykonania się przynajmniej minimalnej liczby min nr operacji, na które oczekujemy lub po minięciu maksymalnego czasu oczekiwania timeout funkcja przekazuje liczbę pobranych zdarzeń zakończenia oraz wypełnia nimi tablicę events (każdej zakończonej operacji odpowiada dokładnie jedno zdarzenie).

Rekord zdarzenia ma postać:

struct io_event {

__u64 data; /* wartość pola aio_data z rekordu kontrolnego */

__u64 obj; /* wskaźnik do rekordu kontrolnego struct iocb */

__s64 res; /* rezultat operacji */

__s64 res2; /* rezultat pomocniczy */

}

gdzie obj jest wskaźnikiem do rekordu kontrolnego zdarzenia, data wartością podaną przez użytkownika w momencie zlecania operacji (pole aiocb->data), a res wynikiem, jakim operacja się zakończyła. (W jądrze 2.6.1 pole res2 nie jest używane).

Rekrod kontrolny

Rekord kontrolny operacji asynchronicznej w systemie Linux zawiera wszystkie wymagane przez POSIX pola.

struct iocb {

__u64 aio_data; /* do wykorzystania przez u»ytkownika */

__u32 PADDED(aio_key, aio_reserved1); /* identyfikator */

__u16 aio_lio_opcode; /* kod przy zlecaniu wielu operacji */

__s16 aio_reqprio; /* priorytet */

__u32 aio_fildes; /* deskryptor pliku */

__u64 aio_buf; /* bufor do odczytu-zapisu */

__u64 aio_nbytes; /* liczba bajtów do odczytu-zapisu */

__s64 aio_offset; /* pozycja w pliku,od której zaczynamy */

__u64 aio_reserved2; /* zarezerwowane, na wsk. sygnaªu */

__u64 aio_reserved3; /* zarezerwowane */

};


Usuwanie kontekstu

Do usuwania kontekstu służy funkcja
int io_destroy(aio_context_t ctx).
W momencie jej wykonania proces traci kontrolę nad kontekstem, a system operacyjny podejmuje próbę odwołania wszystkich związanych z kontekstem operacji, które jeszcze się nie zakończyły.


Źródła

Źródła:


powrót do strony głównej