In questo articolo, utilizzeremo le chiamate di sistema effettive per svolgere un lavoro reale nel nostro programma C. Innanzitutto, esamineremo se è necessario utilizzare una chiamata di sistema, quindi fornire un esempio utilizzando la chiamata SendFile () che può migliorare drasticamente le prestazioni della copia del file. Infine, esamineremo alcuni punti da ricordare durante l'utilizzo delle chiamate di sistema Linux.
Sebbene sia inevitabile, utilizzerai una chiamata di sistema ad un certo punto della tua carriera di sviluppo C, a meno che tu non stia prendendo di mira prestazioni elevate o una particolare funzionalità di tipo, la libreria GLIBC e altre librerie di base incluse nelle principali distribuzioni Linux si occuperanno della maggior parte dei I tuoi bisogni.
La libreria standard GLIBC fornisce un framework multipiattaforma e ben testata per eseguire funzioni che altrimenti richiederebbero chiamate di sistema specifiche del sistema. Ad esempio, puoi leggere un file con fscanf (), fread (), getc (), ecc., oppure puoi utilizzare la chiamata di sistema LEAD () Linux. Le funzioni GLIBC forniscono più funzionalità (i.e. Migliore gestione degli errori, IO formattato, ecc.) e lavorerà su qualsiasi supporto di GLIBC.
D'altra parte, ci sono momenti in cui le prestazioni intransantili e l'esecuzione esatta sono fondamentali. Il wrapper che Fread () fornisce aggiungerà sovraccarico e, sebbene minore, non è del tutto trasparente. Inoltre, non è possibile desiderare o aver bisogno delle funzionalità extra fornite dal wrapper. In tal caso, è meglio servire con una chiamata di sistema.
È inoltre possibile utilizzare le chiamate di sistema per eseguire funzioni non ancora supportate da GLIBC. Se la tua copia di GLIBC è aggiornata, questo difficilmente sarà un problema, ma lo sviluppo di distribuzioni più vecchie con kernel più recenti potrebbe richiedere questa tecnica.
Ora che hai letto le dichiarazioni di non responsabilità, avvertimenti e potenziali deviazioni, ora scaviamo in alcuni esempi pratici.
Su cosa ci stiamo facendo la CPU?
Una domanda che la maggior parte dei programmi probabilmente non pensa di chiedere, ma nefolistica. Questo è un esempio di una chiamata di sistema che non può essere duplicato con glibc e non è coperto da un wrapper Glibc. In questo codice, chiameremo la chiamata getCpu () direttamente tramite la funzione syscall (). La funzione Syscall funziona come segue:
syscall (sys_call, arg1, arg2, ...);Il primo argomento, sys_call, è una definizione che rappresenta il numero della chiamata di sistema. Quando includi sys/syscall.h, questi sono inclusi. La prima parte è sys_ e la seconda parte è il nome della chiamata di sistema.
Argomenti per la chiamata vanno in arg1, arg2 sopra. Alcune chiamate richiedono più argomenti e continueranno in ordine dalla loro pagina uomo. Ricorda che la maggior parte degli argomenti, in particolare per i rendimenti, richiederà indicatori per carbonizzare array o memoria allocata tramite la funzione Malloc.
Esempio 1.C
#includerePer risultati più interessanti, è possibile girare i thread tramite la libreria PThreads e quindi chiamare questa funzione per vedere quale processore è in esecuzione.
Sendfile: prestazioni superiori
Sendfile fornisce un eccellente esempio di miglioramento delle prestazioni tramite le chiamate di sistema. La funzione SendFile () copia i dati da un descrittore di file a un altro. Invece di usare più funzioni Fread () e FWRITE (), SendFile esegue il trasferimento nello spazio del kernel, riducendo le spese generali e aumentando così le prestazioni.
In questo esempio, copriremo 64 MB di dati da un file a un altro. In un test, utilizzeremo i metodi di lettura/scrittura standard nella libreria standard. Nell'altro, utilizzeremo le chiamate di sistema e la chiamata SendFile () per far esplodere questi dati da una posizione a un'altra.
Test1.C (GLIBC)
#includeretest2.C (chiamate di sistema)
#includereProva a compilazione e in esecuzione 1 e 2
Per creare questi esempi, avrai bisogno degli strumenti di sviluppo installati sulla distribuzione. Su Debian e Ubuntu, puoi installarlo con:
APT Installare Build-Essentials
Quindi compilare con:
GCC Test1.c -o test1 && gcc test2.c -o test2
Per eseguire entrambi e testare le prestazioni, eseguire:
tempo ./test1 && time ./test2
Dovresti ottenere risultati come questo:
Test I/O con le funzioni tradizionali GLIBC.
Allocazione di buffer da 64 MB: fattoCome puoi vedere, il codice che utilizza le chiamate di sistema funziona molto più velocemente dell'equivalente GLIBC.
Cose da ricordare
Le chiamate di sistema possono aumentare le prestazioni e fornire funzionalità aggiuntive, ma non sono prive di svantaggi. Dovrai valutare le chiamate del sistema a benefici che forniscono contro la mancanza di portabilità della piattaforma e talvolta ridotta rispetto alle funzioni della libreria.
Quando si utilizza alcune chiamate di sistema, è necessario fare attenzione a utilizzare le risorse restituite dalle chiamate di sistema piuttosto che dalle funzioni della libreria. Ad esempio, la struttura dei file utilizzata per le funzioni Fopen (), Fread (), FWRITE () e fclose () di GLIBC non sono uguali al numero del descrittore dei file dalla chiamata di sistema Open () (restituita come intero). Mescolarli può portare a problemi.
In generale, le chiamate di sistema Linux hanno meno corsie per paraurti rispetto alle funzioni GLIBC. Mentre è vero che le chiamate di sistema hanno alcuni errori di gestione e reporting, otterrai funzionalità più dettagliate da una funzione Glibc.
E infine, una parola sulla sicurezza. Le chiamate di sistema si interfaccia direttamente con il kernel. Il kernel Linux ha ampie protezioni contro gli shenanigans dalla terra dell'utente, ma esistono bug non scoperti. Non fidarti che una chiamata di sistema convaliderà il tuo input o ti isolerà da problemi di sicurezza. È saggio garantire che i dati che consegnate a una chiamata di sistema siano disinfettati. Naturalmente, questo è un buon consiglio per qualsiasi chiamata API, ma non puoi essere attento quando lavori con il kernel.
Spero che ti sia piaciuta questa immersione più profonda nella terra delle chiamate del sistema Linux. Per un elenco completo delle chiamate di sistema Linux, consultare il nostro elenco master.