ఈ వ్యాసంలో, మేము మా సి ప్రోగ్రామ్లో నిజమైన పని చేయడానికి అసలు సిస్టమ్ కాల్లను ఉపయోగించబోతున్నాం. ముందుగా, మీరు సిస్టమ్ కాల్ని ఉపయోగించాల్సిన అవసరం ఉందా అని మేము సమీక్షిస్తాము, ఆపై ఫైల్ కాపీ పనితీరును నాటకీయంగా మెరుగుపరిచే సెండ్ఫైల్ () కాల్ని ఉపయోగించి ఒక ఉదాహరణను అందిస్తాము. చివరగా, మేము Linux సిస్టమ్ కాల్లను ఉపయోగిస్తున్నప్పుడు గుర్తుంచుకోవలసిన కొన్ని పాయింట్లను పరిశీలిస్తాము.
ఇది అనివార్యమైనప్పటికీ, మీరు మీ C డెవలప్మెంట్ కెరీర్లో ఏదో ఒక సమయంలో సిస్టమ్ కాల్ని ఉపయోగిస్తారు, మీరు అధిక పనితీరు లేదా నిర్దిష్ట రకం కార్యాచరణను లక్ష్యంగా పెట్టుకోకపోతే, glibc లైబ్రరీ మరియు ఇతర లైనక్స్ డిస్ట్రిబ్యూషన్లలో చేర్చబడిన ఇతర ప్రాథమిక లైబ్రరీలు చాలా వరకు జాగ్రత్త వహిస్తాయి. మీ అవసరాలు.
సిస్టమ్-నిర్దిష్ట సిస్టమ్ కాల్లు అవసరమయ్యే ఫంక్షన్లను అమలు చేయడానికి glibc స్టాండర్డ్ లైబ్రరీ క్రాస్ ప్లాట్ఫాం, బాగా పరీక్షించిన ఫ్రేమ్వర్క్ను అందిస్తుంది. ఉదాహరణకు, మీరు fscanf (), fread (), getc (), మొదలైన వాటితో ఒక ఫైల్ని చదవవచ్చు లేదా మీరు రీడ్ () Linux సిస్టమ్ కాల్ని ఉపయోగించవచ్చు. Glibc ఫంక్షన్లు మరిన్ని ఫీచర్లను అందిస్తాయి (అనగా మెరుగైన ఎర్రర్ హ్యాండ్లింగ్, ఫార్మాట్ IO, మొదలైనవి) మరియు ఏదైనా సిస్టమ్ glibc సపోర్ట్లపై పని చేస్తుంది.
మరోవైపు, రాజీలేని పనితీరు మరియు ఖచ్చితమైన అమలు కీలకమైన సందర్భాలు ఉన్నాయి. ఫ్రెడ్ () అందించే రేపర్ ఓవర్హెడ్ను జోడించబోతోంది, మరియు చిన్నది అయినప్పటికీ, పూర్తిగా పారదర్శకంగా ఉండదు. అదనంగా, రేపర్ అందించే అదనపు ఫీచర్లను మీరు కోరుకోకపోవచ్చు లేదా అవసరం ఉండకపోవచ్చు. ఆ సందర్భంలో, మీకు సిస్టమ్ కాల్తో ఉత్తమంగా సేవలు అందించబడతాయి.
మీరు ఇంకా glibc ద్వారా సపోర్ట్ చేయని ఫంక్షన్లను నిర్వహించడానికి సిస్టమ్ కాల్లను కూడా ఉపయోగించవచ్చు. మీ glibc కాపీ తాజాగా ఉంటే, ఇది సమస్య కాదు, కానీ పాత కెర్నల్స్తో పాత డిస్ట్రిబ్యూషన్ల అభివృద్ధికి ఈ టెక్నిక్ అవసరం కావచ్చు.
ఇప్పుడు మీరు నిరాకరణలు, హెచ్చరికలు మరియు సంభావ్య ప్రక్కమార్గాలను చదివినందున, ఇప్పుడు కొన్ని ఆచరణాత్మక ఉదాహరణలను పరిశీలిద్దాం.
మేము ఏ CPU లో ఉన్నాము?
చాలా ప్రోగ్రామ్లు బహుశా అడగాలని అనుకోని ప్రశ్న, అయితే చెల్లుబాటు అయ్యేది. ఇది glibc తో డూప్లికేట్ చేయలేని మరియు గ్లిబ్సీ రేపర్తో కవర్ చేయని సిస్టమ్ కాల్కు ఉదాహరణ. ఈ కోడ్లో, మేము syscall () ఫంక్షన్ ద్వారా నేరుగా getcpu () కాల్కు కాల్ చేస్తాము. సిస్కాల్ ఫంక్షన్ క్రింది విధంగా పనిచేస్తుంది:
సిస్కాల్(SYS_ కాల్,ఆర్గ్ 1,ఆర్గ్ 2,...);మొదటి వాదన, SYS_call, సిస్టమ్ కాల్ సంఖ్యను సూచించే నిర్వచనం. మీరు sys/syscall.h ని చేర్చినప్పుడు, ఇవి చేర్చబడతాయి. మొదటి భాగం SYS_ మరియు రెండవ భాగం సిస్టమ్ కాల్ పేరు.
కాల్ కోసం వాదనలు పైన arg1, arg2 లోకి వెళ్తాయి. కొన్ని కాల్లకు మరిన్ని వాదనలు అవసరం, మరియు అవి వారి మ్యాన్ పేజీ నుండి క్రమంలో కొనసాగుతాయి. చాలా వాదనలు, ప్రత్యేకించి రిటర్న్ల కోసం, మలోక్ ఫంక్షన్ ద్వారా కేటాయించిన శ్రేణులు లేదా మెమరీని చార్టర్ చేయడానికి పాయింటర్లు అవసరమవుతాయని గుర్తుంచుకోండి.
ఉదాహరణ 1. సి
#చేర్చండి#చేర్చండి
#చేర్చండి
#చేర్చండి
intప్రధాన() {
సంతకం చేయలేదుcpu,నోడ్;
// సిస్టమ్ కాల్ ద్వారా ప్రస్తుత CPU కోర్ మరియు NUMA నోడ్ పొందండి
// దీనికి glibc రేపర్ లేదు కాబట్టి మనం నేరుగా కాల్ చేయాలి
సిస్కాల్(SYS_getcpu, &cpu, &నోడ్,శూన్య);
// ప్రదర్శన సమాచారం
printf ('ఈ ప్రోగ్రామ్ CPU కోర్ %u మరియు NUMA నోడ్ %u లో నడుస్తోంది. n n',cpu,నోడ్);
తిరిగి 0;
}
కంపైల్ మరియు అమలు చేయడానికి:
gcc ఉదాహరణ 1.c -ఉదాహరణ 1
./ఉదాహరణ 1
మరింత ఆసక్తికరమైన ఫలితాల కోసం, మీరు pthreads లైబ్రరీ ద్వారా థ్రెడ్లను స్పిన్ చేయవచ్చు మరియు మీ థ్రెడ్ ఏ ప్రాసెసర్పై నడుస్తుందో చూడటానికి ఈ ఫంక్షన్కు కాల్ చేయవచ్చు.
Sendfile: ఉన్నతమైన పనితీరు
సిస్టమ్ కాల్ల ద్వారా పనితీరును పెంచడానికి సెండ్ఫైల్ అద్భుతమైన ఉదాహరణను అందిస్తుంది. పంపే ఫైల్ () ఫంక్షన్ ఒక ఫైల్ డిస్క్రిప్టర్ నుండి మరొకదానికి డేటాను కాపీ చేస్తుంది. బహుళ fread () మరియు fwrite () ఫంక్షన్లను ఉపయోగించే బదులు, సెండ్ఫైల్ కెర్నల్ స్పేస్లో బదిలీని నిర్వహిస్తుంది, ఓవర్హెడ్ను తగ్గిస్తుంది మరియు తద్వారా పనితీరును పెంచుతుంది.
ఈ ఉదాహరణలో, మేము 64 MB డేటాను ఒక ఫైల్ నుండి మరొక ఫైల్కు కాపీ చేయబోతున్నాం. ఒక పరీక్షలో, మేము ప్రామాణిక లైబ్రరీలో ప్రామాణిక రీడ్/రైట్ పద్ధతులను ఉపయోగించబోతున్నాం. మరొకదానిలో, ఈ డేటాను ఒక ప్రదేశం నుండి మరొక ప్రదేశానికి పేల్చడానికి మేము సిస్టమ్ కాల్లు మరియు సెండ్ఫైల్ () కాల్ని ఉపయోగిస్తాము.
test1.c (glibc)
#చేర్చండి#చేర్చండి
#చేర్చండి
#చేర్చండి
#BUFFER_SIZE 67108864 ని నిర్వచించండి
#బఫర్_1 'బఫర్ 1' ని నిర్వచించండి
#బఫర్_2 'బఫర్ 2' ని నిర్వచించండి
intప్రధాన() {
ఫైల్*తప్పు, *ముగింపు;
printf (' nసాంప్రదాయ glibc ఫంక్షన్లతో I/O పరీక్ష. n n');
// BUFFER_SIZE బఫర్ని పట్టుకోండి.
// బఫర్లో యాదృచ్ఛిక డేటా ఉంటుంది కానీ మేము దాని గురించి పట్టించుకోము.
printf ('64 MB బఫర్ కేటాయించడం:');
చార్ *బఫర్= (చార్ *) malloc (BUFFER_SIZE);
printf ('పూర్తి n');
// బఫర్ను ఫౌట్కి వ్రాయండి
printf ('మొదటి బఫర్కు డేటాను వ్రాయడం:');
తప్పు= fopen (బఫర్_1, 'wb');
fwrite (బఫర్, పరిమాణం(చార్),BUFFER_SIZE,తప్పు);
fclose (తప్పు);
printf ('పూర్తి n');
printf ('మొదటి ఫైల్ నుండి రెండవదానికి డేటాను కాపీ చేస్తోంది:');
ముగింపు= fopen (బఫర్_1, 'rb');
తప్పు= fopen (బఫర్_2, 'wb');
fread (బఫర్, పరిమాణం(చార్),BUFFER_SIZE,ముగింపు);
fwrite (బఫర్, పరిమాణం(చార్),BUFFER_SIZE,తప్పు);
fclose (ముగింపు);
fclose (తప్పు);
printf ('పూర్తి n');
printf ('ఉచిత బఫర్:');
ఉచిత (బఫర్);
printf ('పూర్తి n');
printf ('ఫైళ్లను తొలగిస్తోంది:');
తొలగించు (బఫర్_1);
తొలగించు (బఫర్_2);
printf ('పూర్తి n');
తిరిగి 0;
}
test2.c (సిస్టమ్ కాల్స్)
#చేర్చండి#చేర్చండి
#చేర్చండి
#చేర్చండి
#చేర్చండి
#చేర్చండి
#చేర్చండి
#చేర్చండి
#చేర్చండి
#BUFFER_SIZE 67108864 ని నిర్వచించండి
intప్రధాన() {
intతప్పు,ముగింపు;
printf (' nSendfile () మరియు సంబంధిత సిస్టమ్ కాల్లతో I/O పరీక్ష. n n');
// BUFFER_SIZE బఫర్ని పట్టుకోండి.
// బఫర్లో యాదృచ్ఛిక డేటా ఉంటుంది కానీ మేము దాని గురించి పట్టించుకోము.
printf ('64 MB బఫర్ కేటాయించడం:');
చార్ *బఫర్= (చార్ *) malloc (BUFFER_SIZE);
printf ('పూర్తి n');
// బఫర్ను ఫౌట్కి వ్రాయండి
printf ('మొదటి బఫర్కు డేటాను వ్రాయడం:');
తప్పు=తెరవండి('బఫర్ 1',O_RDONLY);
వ్రాయడానికి(తప్పు, &బఫర్,BUFFER_SIZE);
దగ్గరగా(తప్పు);
printf ('పూర్తి n');
printf ('మొదటి ఫైల్ నుండి రెండవదానికి డేటాను కాపీ చేస్తోంది:');
ముగింపు=తెరవండి('బఫర్ 1',O_RDONLY);
తప్పు=తెరవండి('బఫర్ 2',O_RDONLY);
ఫైల్ పంపించు(తప్పు,ముగింపు, 0,BUFFER_SIZE);
దగ్గరగా(ముగింపు);
దగ్గరగా(తప్పు);
printf ('పూర్తి n');
printf ('ఉచిత బఫర్:');
ఉచిత (బఫర్);
printf ('పూర్తి n');
printf ('ఫైళ్లను తొలగిస్తోంది:');
అన్లింక్ చేయండి('బఫర్ 1');
అన్లింక్ చేయండి('బఫర్ 2');
printf ('పూర్తి n');
తిరిగి 0;
}
1 & 2 పరీక్షలను కంపైల్ చేయడం మరియు అమలు చేయడం
ఈ ఉదాహరణలను రూపొందించడానికి, మీ పంపిణీలో ఇన్స్టాల్ చేయబడిన అభివృద్ధి సాధనాలు మీకు అవసరం. డెబియన్ మరియు ఉబుంటులో, మీరు దీన్ని దీనితో ఇన్స్టాల్ చేయవచ్చు:
సముచితమైనదిఇన్స్టాల్బిల్డ్-ఎసెన్షియల్స్అప్పుడు దీనితో కంపైల్ చేయండి:
gccపరీక్ష 1. సి-లేదాపరీక్ష 1&& gccపరీక్ష 2. సి-లేదాపరీక్ష 2రెండింటినీ అమలు చేయడానికి మరియు పనితీరును పరీక్షించడానికి, అమలు చేయండి:
సమయం./పరీక్ష 1&& సమయం./పరీక్ష 2మీరు ఇలాంటి ఫలితాలను పొందాలి:
సాంప్రదాయ glibc ఫంక్షన్లతో I/O పరీక్ష.
64 MB బఫర్ కేటాయించడం: పూర్తయిందిమొదటి బఫర్కు డేటాను వ్రాయడం: పూర్తయింది
మొదటి ఫైల్ నుండి రెండవదానికి డేటాను కాపీ చేస్తోంది: పూర్తయింది
ఉచిత బఫర్: పూర్తయింది
ఫైళ్ళను తొలగిస్తోంది: పూర్తయింది
నిజమైన 0m0.397s
వినియోగదారు 0m0.000s
sys 0m0.203s
Sendfile () మరియు సంబంధిత సిస్టమ్ కాల్లతో I/O పరీక్ష.
64 MB బఫర్ కేటాయించడం: పూర్తయింది
మొదటి బఫర్కు డేటాను వ్రాయడం: పూర్తయింది
మొదటి ఫైల్ నుండి రెండవదానికి డేటాను కాపీ చేస్తోంది: పూర్తయింది
ఉచిత బఫర్: పూర్తయింది
ఫైళ్ళను తొలగిస్తోంది: పూర్తయింది
నిజమైన 0m0.019 సె
వినియోగదారు 0m0.000s
sys 0m0.016s
మీరు గమనిస్తే, సిస్టమ్ కాల్లను ఉపయోగించే కోడ్ గ్లిబిసి సమానమైన దానికంటే చాలా వేగంగా నడుస్తుంది.
గుర్తుంచుకోవలసిన విషయాలు
సిస్టమ్ కాల్లు పనితీరును పెంచుతాయి మరియు అదనపు కార్యాచరణను అందించగలవు, కానీ అవి వాటి నష్టాలు లేకుండా ఉండవు. ప్లాట్ఫారమ్ పోర్టబిలిటీ లేకపోవడం మరియు లైబ్రరీ ఫంక్షన్లతో పోలిస్తే కొన్నిసార్లు తగ్గిన కార్యాచరణకు వ్యతిరేకంగా సిస్టమ్ కాల్లు అందించే ప్రయోజనాలను మీరు అంచనా వేయాలి.
కొన్ని సిస్టమ్ కాల్లను ఉపయోగిస్తున్నప్పుడు, లైబ్రరీ ఫంక్షన్ల కంటే సిస్టమ్ కాల్ల నుండి వచ్చే వనరులను ఉపయోగించడానికి మీరు జాగ్రత్త వహించాలి. ఉదాహరణకు, glibc యొక్క fopen (), fread (), fwrite (), మరియు fclose () ఫంక్షన్లకు ఉపయోగించే ఫైల్ నిర్మాణం ఓపెన్ () సిస్టమ్ కాల్ (పూర్ణాంకంగా తిరిగి వచ్చింది) నుండి ఫైల్ డిస్క్రిప్టర్ నంబర్తో సమానంగా ఉండదు. వీటిని కలపడం సమస్యలకు దారితీస్తుంది.
సాధారణంగా, Linux సిస్టమ్ కాల్లు glibc ఫంక్షన్ల కంటే తక్కువ బంపర్ లేన్లను కలిగి ఉంటాయి. సిస్టమ్ కాల్లలో కొంత లోపం నిర్వహణ మరియు రిపోర్టింగ్ ఉన్నది నిజమే అయితే, మీరు glibc ఫంక్షన్ నుండి మరింత వివరణాత్మక కార్యాచరణను పొందుతారు.
చివరకు, భద్రతపై ఒక మాట. సిస్టమ్ కాల్స్ నేరుగా కెర్నల్తో ఇంటర్ఫేస్ చేస్తుంది. లైనక్స్ కెర్నల్ యూజర్ ల్యాండ్ నుండి షెనానిగాన్లకు వ్యతిరేకంగా విస్తృతమైన రక్షణలను కలిగి ఉంది, కానీ కనుగొనబడని బగ్లు ఉన్నాయి. సిస్టమ్ కాల్ మీ ఇన్పుట్ను ధృవీకరిస్తుందని లేదా భద్రతా సమస్యల నుండి మిమ్మల్ని వేరుచేస్తుందని విశ్వసించవద్దు. సిస్టమ్ కాల్కు మీరు అందజేసే డేటా శుద్ధీకరించబడిందని నిర్ధారించుకోవడం మంచిది. సహజంగా, ఏదైనా API కాల్కు ఇది మంచి సలహా, కానీ కెర్నల్తో పనిచేసేటప్పుడు మీరు జాగ్రత్తగా ఉండలేరు.
లైనక్స్ సిస్టమ్ కాల్ల భూమికి మీరు ఈ లోతైన డైవ్ను ఆస్వాదించారని నేను ఆశిస్తున్నాను. Linux సిస్టమ్ కాల్ల పూర్తి జాబితా కోసం, మా మాస్టర్ జాబితాను చూడండి.