C programavimas

„Linux“ sistemos skambučių pamoka su C

„Linux“ sistemos skambučių pamoka su C
Paskutiniame mūsų straipsnyje apie „Linux“ sistemos skambučius aš apibrėžiau sistemos iškvietimą, aptariau priežastis, dėl kurių juos galima naudoti programoje, ir gilinausi į jų pranašumus bei trūkumus. Aš net pateikiau trumpą pavyzdį surinkdamas C. Tai iliustruoja punktą ir aprašo, kaip paskambinti, tačiau nieko nedarė. Ne visai jaudinantis vystymosi pratimas, bet jis iliustruoja esmę.

Šiame straipsnyje mes naudosime faktinius sistemos skambučius, kad atliktume realų darbą mūsų C programoje. Pirmiausia peržiūrėsime, ar jums reikia naudoti sistemos skambutį, tada pateikite pavyzdį naudodami „sendfile“ () skambutį, kuris gali žymiai pagerinti failo kopijavimo našumą. Galiausiai apžvelgsime keletą dalykų, kuriuos turėtume prisiminti naudodami „Linux“ sistemos skambučius.

Ar jums reikia sistemos skambučio?

Nors tai neišvengiama, tam tikru savo „C“ kūrimo karjeros momentu naudosite sistemos iškvietimą, nebent jūs siekiate didelio našumo ar tam tikro tipo funkcionalumo, „glibc“ biblioteka ir kitos pagrindinės bibliotekos, įtrauktos į pagrindinius „Linux“ paskirstymus, pasirūpins dauguma savo poreikius.

„Glibc“ standartinė biblioteka suteikia daugiaplatformę, gerai patikrintą sistemą funkcijoms vykdyti, kurioms priešingu atveju prireiktų sistemos specifinių skambučių. Pvz., Galite perskaityti failą naudodami fscanf (), fread (), getc () ir kt., arba galite naudoti skaitytą () „Linux“ sistemos iškvietimą. Glibc funkcijos suteikia daugiau funkcijų (t.e. geresnis klaidų tvarkymas, suformatuotas IO ir kt.) ir veiks su bet kokia sistemos glibc palaikymu.

Kita vertus, yra atvejų, kai be kompromisų atlikimas ir tikslus vykdymas yra labai svarbūs. „Fread“ () teikiama pakuotė pridės pridėtines išlaidas, ir, nors ir nedidelė, nėra visiškai skaidri. Be to, jums gali nenorėti ar nereikėti papildomų funkcijų, kurias suteikia pakuotė. Tokiu atveju jums geriausiai tinka sistemos skambutis.

Taip pat galite naudoti sistemos skambučius funkcijoms, kurių dar nepalaiko glibc. Jei jūsų glibc kopija yra atnaujinta, tai vargu ar bus problema, tačiau kuriant senesnius paskirstymus su naujesniais branduoliais gali prireikti šios technikos.

Dabar, kai perskaitėte atsisakymus, įspėjimus ir galimus apvažiavimo kelius, dabar įsigilinkime į keletą praktinių pavyzdžių.

Koks procesorius yra?

Klausimas, kurio tikriausiai nemąsto užduoti dauguma programų, tačiau vis dėlto pagrįstas. Tai yra sistemos skambučio, kurio negalima dubliuoti su „glibc“ ir kuris nėra padengtas „glibc“ apvalkalu, pavyzdys. Šiame kode mes skambinsime getcpu () skambučiu tiesiogiai per syscall () funkciją. „Syscall“ funkcija veikia taip:

syscall (SYS_call, arg1, arg2,…);

Pirmasis argumentas „SYS_call“ yra apibrėžimas, nurodantis sistemos iškvietimo numerį. Kai įtraukiate sys / syscall.h, jie yra įtraukti. Pirmoji dalis yra SYS_, o antroji dalis yra sistemos iškvietimo pavadinimas.

Skambučio argumentai eina į arg1, arg2 aukščiau. Kai kuriems skambučiams reikia daugiau argumentų ir jie bus tvarkingi toliau iš savo vyro puslapio. Atminkite, kad daugumai argumentų, ypač dėl grąžinimo, reikės rodyklių į simbolių masyvus arba atmintį, skirtą per malloc funkciją.

1 pavyzdys.c

# įtraukti
# įtraukti
# įtraukti
# įtraukti
 
int main ()
 
nepasirašytas procesorius, mazgas;
 
// Gauti dabartinį procesoriaus šerdį ir NUMA mazgą per sistemos skambutį
// Atkreipkite dėmesį, kad jame nėra „glibc“ įvyniojimo, todėl turime jį paskambinti tiesiogiai
syscall (SYS_getcpu, & cpu, & node, NULL);
 
// Rodyti informaciją
printf ("Ši programa veikia procesoriaus šerdyje% u ir NUMA mazge% u.\ n \ n ", procesorius, mazgas);
 
grąžinti 0;
 

 
Norėdami sudaryti ir paleisti:
 
gcc pavyzdys.c -o pavyzdys1
./ pavyzdys1

Norėdami gauti įdomesnių rezultatų, galite suktis gijas per pthreads biblioteką ir paskambinę į šią funkciją pamatysite, kuriame procesoriuje jūsų gija veikia.

„Sendfile“: puikus našumas

„Sendfile“ yra puikus našumo gerinimo naudojant sistemos skambučius pavyzdys. Funkcija sendfile () nukopijuoja duomenis iš vieno failo aprašo į kitą. Užuot naudojęs kelias „fread“ () ir „fwrite“) funkcijas, „sendfile“ atlieka perdavimą branduolio erdvėje, sumažindamas pridėtines išlaidas ir taip padidindamas našumą.

Šiame pavyzdyje mes nukopijuosime 64 MB duomenų iš vieno failo į kitą. Vieno bandymo metu mes naudosime standartinius skaitymo / rašymo metodus standartinėje bibliotekoje. Kitame naudosime sistemos skambučius ir „sendfile“ () skambutį, kad sprogdintume šiuos duomenis iš vienos vietos į kitą.

testas1.c (glibc)

# įtraukti
# įtraukti
# įtraukti
# įtraukti
 
#define BUFFER_SIZE 67108864
#define BUFFER_1 "buferis1"
#define BUFFER_2 "buferis2"
 
int main ()
 
FILE * fOut, * fIn;
 
printf ("\ nI / O testas su tradicinėmis glibc funkcijomis.\ n \ n ");
 
// Paimkite BUFFER_SIZE buferį.
// Buferis turės atsitiktinius duomenis, bet mums tai nerūpi.
printf ("64 MB buferio paskirstymas:");
char * buferis = (char *) malloc (BUFFER_SIZE);
printf ("ATLIKTA \ n");
 
// Parašykite buferį į fOut
printf ("Duomenų rašymas į pirmąjį buferį:");
fOut = fopen (BUFFER_1, "wb");
fwrite (buferis, sizeof (char), BUFFER_SIZE, fOut);
fclose (fOut);
printf ("ATLIKTA \ n");
 
printf ("Duomenų kopijavimas iš pirmo failo į antrą:");
fIn = fopen (BUFFER_1, "rb");
fOut = fopen (BUFFER_2, "wb");
duona (buferis, sizeof (char), BUFFER_SIZE, fIn);
fwrite (buferis, sizeof (char), BUFFER_SIZE, fOut);
fclose (fIn);
fclose (fOut);
printf ("ATLIKTA \ n");
 
printf ("Atlaisvinimo buferis:");
laisvas (buferis);
printf ("ATLIKTA \ n");
 
printf ("Failų trynimas:");
pašalinti (BUFFER_1);
pašalinti (BUFFER_2);
printf ("ATLIKTA \ n");
 
grąžinti 0;
 

testas2.c (sistemos skambučiai)

# įtraukti
# įtraukti
# įtraukti
# įtraukti
# įtraukti
# įtraukti
# įtraukti
# įtraukti
# įtraukti
 
#define BUFFER_SIZE 67108864
 
int main ()
 
int fOut, fIn;
 
printf ("\ nI / O testas su sendfile () ir susijusiais sistemos iškvietimais.\ n \ n ");
 
// Paimkite BUFFER_SIZE buferį.
// Buferis turės atsitiktinius duomenis, bet mums tai nerūpi.
printf ("64 MB buferio paskirstymas:");
char * buferis = (char *) malloc (BUFFER_SIZE);
printf ("ATLIKTA \ n");
 
// Parašykite buferį į fOut
printf ("Duomenų rašymas į pirmąjį buferį:");
fOut = atidaryti ("buferis1", O_RDONLY);
rašyti (fOut, & buffer, BUFFER_SIZE);
uždaryti (fOut);
printf ("ATLIKTA \ n");
 
printf ("Duomenų kopijavimas iš pirmo failo į antrą:");
fIn = atviras ("buferis1", O_RDONLY);
fOut = atidaryti ("buferis2", O_RDONLY);
sendfile (fOut, fIn, 0, BUFFER_SIZE);
uždaryti (fIn);
uždaryti (fOut);
printf ("ATLIKTA \ n");
 
printf ("Atlaisvinimo buferis:");
laisvas (buferis);
printf ("ATLIKTA \ n");
 
printf ("Failų trynimas:");
atsieti ("buferis1");
atsieti ("buferis2");
printf ("ATLIKTA \ n");
 
grąžinti 0;
 

1 ir 2 bandymų sudarymas ir vykdymas

Norėdami sukurti šiuos pavyzdžius, jums reikės jūsų platinimo programoje įdiegtų kūrimo įrankių. „Debian“ ir „Ubuntu“ galite tai įdiegti naudodami:

„apt install build-essentials“

Tada sudarykite:

gcc testas.c -o test1 ir & gcc test2.c -o testas2

Norėdami paleisti abu ir išbandyti našumą, paleiskite:

laikas ./ test1 && laikas ./ testas2

Turėtumėte gauti tokius rezultatus:

I / O testas su tradicinėmis glibc funkcijomis.

Skiriamas 64 MB buferis: ATLIKTA
Duomenų rašymas į pirmąjį buferį: ATLIKTA
Duomenų kopijavimas iš pirmo failo į antrą: ATLIKTA
Atlaisvinamasis buferis: ATLIKTA
Failų trynimas: ATLIKTA
tikras 0m0.397-ieji
vartotojas 0m0.000s
sys 0m0.203-ieji
I / O testas su sendfile () ir susijusiais sistemos iškvietimais.
Skiriamas 64 MB buferis: ATLIKTA
Duomenų rašymas į pirmąjį buferį: ATLIKTA
Duomenų kopijavimas iš pirmo failo į antrą: ATLIKTA
Atlaisvinamasis buferis: ATLIKTA
Failų trynimas: ATLIKTA
tikras 0m0.019-ieji
vartotojas 0m0.000s
sys 0m0.016-ieji

Kaip matote, kodas, kuris naudoja sistemos skambučius, veikia daug greičiau nei „glibc“ atitikmuo.

Ką reikia atsiminti

Sisteminiai skambučiai gali padidinti našumą ir suteikti papildomų funkcijų, tačiau jie nėra be trūkumų. Turėsite pasverti sistemos skambučių teikiamą naudą su platformos perkeliamumo trūkumu ir kartais sumažėjusiu funkcionalumu, palyginti su bibliotekos funkcijomis.

Kai naudojate kai kuriuos sistemos skambučius, turite naudoti ne bibliotekos funkcijas, o iš sistemos skambučių gautus išteklius. Pvz., FILE struktūra, naudojama glibc funkcijoms „fopen“ (), fread (), fwrite () ir fclose (), nėra tas pats, kas failo deskriptoriaus numeris iš „open“ (sistemos skambučio) (grąžinamas kaip sveikas skaičius). Jų sumaišymas gali sukelti problemų.

Apskritai „Linux“ sistemos skambučiuose yra mažiau buferio juostų nei „glibc“ funkcijose. Nors tiesa, kad sistemos skambučiuose yra tam tikrų klaidų tvarkymo ir ataskaitų teikimo, išsamesnes funkcijas gausite iš „glibc“ funkcijos.

Ir galiausiai, žodis apie saugumą. Sistemos skambučiai tiesiogiai sąsaja su branduoliu. „Linux“ branduolys turi plačią apsaugą nuo šenaniganų iš vartotojo žemės, tačiau yra neatrastų klaidų. Nepasitikėkite, kad sistemos skambutis patvirtins jūsų įvestį arba išskirs jus nuo saugumo problemų. Protinga užtikrinti, kad duomenys, kuriuos perduodate sistemos iškvietimui, būtų išvalyti. Natūralu, kad tai yra geras patarimas atliekant bet kokį API skambutį, tačiau dirbdami su branduoliu negalite būti atsargūs.

Tikiuosi, kad jums patiko šis gilesnis pasinerimas į „Linux“ sistemos skambučių šalį. Išsamų „Linux“ sistemos skambučių sąrašą rasite mūsų pagrindiniame sąraše.

Mėgdžiokite pelės paspaudimus, užveskite pelės žymeklį naudodami pelę „Clickless Mouse“ sistemoje „Windows 10“
Pelės ar klaviatūros naudojimas netinkamoje laikysenoje, kai naudojama per daug, gali sukelti daug sveikatos problemų, įskaitant įtampą, riešo kanalo ...
Pridėkite pelės gestus prie „Windows 10“ naudodami šiuos nemokamus įrankius
Pastaraisiais metais kompiuteriai ir operacinės sistemos labai išsivystė. Buvo laikas, kai vartotojai turėjo naudoti komandas naršydami per failų tvar...
Valdykite ir valdykite pelės judėjimą tarp kelių „Windows 10“ monitorių
„Dual Display Mouse Manager“ leidžia jums valdyti ir konfigūruoti pelės judėjimą tarp kelių monitorių, sulėtinant jo judėjimą šalia sienos. „Windows 1...