W tym artykule użyjemy rzeczywistych połączeń systemowych, aby wykonywać prawdziwą pracę w naszym programie C. Najpierw przejrzymy, jeśli będziesz musiał użyć połączenia systemowego, podaj przykład za pomocą wywołania sendFile (), który może znacznie poprawić wydajność kopiowania plików. Na koniec omówimy kilka punktów do zapamiętania podczas korzystania z połączeń systemowych Linux.
Chociaż jest to nieuniknione, użyjesz połączenia systemowego w pewnym momencie swojej kariery rozwojowej C, chyba że kierujesz się wysoką wydajnością lub określoną funkcją, biblioteka GLIBC i inne podstawowe biblioteki zawarte w dużych rozkładach Linux zajmie się większością Twoje potrzeby.
Biblioteka standardowa GLIBC zapewnia wieloplatformową, dobrze przetestowaną framework do wykonywania funkcji, które w przeciwnym razie wymagałyby wywołania systemu specyficznego dla systemu. Na przykład możesz odczytać plik z fscanf (), fread (), getC () itp., lub możesz użyć wywołania systemu Linux Linux. Funkcje GLIBC zapewniają więcej funkcji (i.mi. Lepsze obsługi błędów, sformatowane IO itp.) i będzie działać na dowolnym systemie obsługi GLIBC.
Z drugiej strony są czasy, w których bezkompromisowa wydajność i dokładne wykonanie są krytyczne. Opakowanie, które zapewnia Fread (), doda koszty ogólne i choć niewielkie, nie jest całkowicie przejrzyste. Dodatkowo możesz nie chcieć lub potrzebujesz dodatkowych funkcji, które podaje opakowanie. W takim przypadku najlepiej służyć z rozmową systemową.
Możesz także używać wywołań systemowych do wykonywania funkcji, które nie są jeszcze obsługiwane przez Glibc. Jeśli twoja kopia Glibc jest aktualna, nie będzie to problemem, ale opracowanie starszych dystrybucji z nowszymi jądrami może wymagać tej techniki.
Teraz, gdy przeczytałeś zrzeczenia się, ostrzeżenia i potencjalne objazdy, teraz zagłębiajmy się w niektóre praktyczne przykłady.
Na jakim procesorze jesteśmy?
Pytanie, którego większość programów prawdopodobnie nie ma, ale mimo to ważne. To jest przykład wywołania systemowego, którego nie można powielić za pomocą glibc i nie jest pokryte opakowaniem glibc. W tym kodzie wywołamy wywołanie getCPu () bezpośrednio za pomocą funkcji SysScall (). Funkcja Syscall działa w następujący sposób:
SYSCALL (SYS_CALL, Arg1, Arg2,…);Pierwszy argument, sys_call, to definicja reprezentująca liczbę wywołania systemu. Po uwzględnieniu SYS/SYSCALL.h, są one wliczone. Pierwsza część to Sys_, a druga część to nazwa wywołania systemu.
Argumenty za wezwaniem przejdź do arg1, arg2 powyżej. Niektóre połączenia wymagają większej liczby argumentów i będą kontynuować na stronie Man. Pamiętaj, że większość argumentów, szczególnie w przypadku zwrotów, będzie wymagać wskaźników do tablic szarań lub pamięci przydzielonej za pośrednictwem funkcji Malloc.
Przykład 1.C
#włączaćAby uzyskać więcej interesujących rezultat.
Sendfile: doskonała wydajność
SendFile stanowi doskonały przykład zwiększania wydajności za pomocą wywołań systemowych. Funkcja sendFile () kopiuje dane z jednego deskryptora pliku do drugiego. Zamiast używać wielu funkcji Fread () i Fwrite (), SendFile wykonuje transfer w przestrzeni jądra, zmniejszając ogólne narzut, a tym samym zwiększając wydajność.
W tym przykładzie skopiujemy 64 MB danych z jednego pliku do drugiego. W jednym teście użyjemy standardowych metod odczytu/zapisu w standardowej bibliotece. Z drugiej strony użyjemy połączeń systemowych i wywołania sendFile (), aby wysadzić te dane z jednej lokalizacji do drugiej.
test1.C (GLIBC)
#włączaćtest2.C (wywołania systemowe)
#włączaćTesty kompilacji i uruchamiania 1 i 2
Aby zbudować te przykłady, będziesz potrzebować narzędzi programistycznych zainstalowanych w dystrybucji. W Debian i Ubuntu możesz to zainstalować z:
apt instal instaluj liczbę kompilacji
Następnie skompiluj z:
test GCC1.C -O TEST1 && GCC TEST2.C -O TEST2
Aby uruchomić oba i przetestować wydajność, uruchom:
czas ./TEST1 && czas ./test2
Powinieneś uzyskać takie wyniki:
Test I/O z tradycyjnymi funkcjami GLIBC.
Przydzielanie bufora 64 MB: gotoweJak widać, kod, który korzysta z połączeń systemowych, działa znacznie szybciej niż równoważnik GLIBC.
Rzeczy do zapamiętania
Wywołania systemowe mogą zwiększyć wydajność i zapewnić dodatkową funkcjonalność, ale nie są pozbawione ich wad. Będziesz musiał zważyć korzyści, które wywoływają systemy, które zapewniają brak przenośności platformy, a czasem zmniejszona funkcjonalność w porównaniu z funkcjami biblioteki.
Korzystając z niektórych połączeń systemowych, musisz uważać na korzystanie z zasobów zwróconych z wywołań systemowych, a nie funkcji biblioteki. Na przykład struktura pliku używana do funkcji Fopen (), Fread (), fwrite () i fclose () nie są takie same jak numer deskryptora pliku z wywołania systemowego Open () (zwrócone jako liczba całkowita). Mieszanie ich może prowadzić do problemów.
Zasadniczo wywołania systemu Linux mają mniej pasów zderzaków niż funkcje GLIBC. Chociaż prawdą jest, że wywołania systemowe mają pewne obsługę błędów i raportowanie, otrzymasz bardziej szczegółową funkcjonalność z funkcji Glibc.
I wreszcie słowo o bezpieczeństwie. System wywołuje bezpośrednio interfejs z jądrem. Kernel Linux ma obszerną ochronę przed shenanigans przed ziemią użytkownika, ale istnieją nieodkryte błędy. Nie ufaj, że połączenie systemowe potwierdzi twoje dane wejściowe lub odizolują Cię od problemów związanych z bezpieczeństwem. Rozsądnie jest upewnienie się, że dane, które przekazujesz do połączenia systemowego, są zdezynfekowane. Oczywiście jest to dobra rada dla każdego wezwania API, ale nie możesz być ostrożny podczas pracy z jądrem.
Mam nadzieję, że podobało Ci się to głębsze zanurzenie się w krainie połączeń systemowych Linux. Aby uzyskać pełną listę połączeń systemowych Linux, zobacz naszą listę główną.