লিনাক্স সিস্টেম কল টিউটোরিয়াল সি দিয়ে

Linux System Call Tutorial With C



আমাদের শেষ নিবন্ধে লিনাক্স সিস্টেম কল , আমি একটি সিস্টেম কল সংজ্ঞায়িত করেছি, একটি প্রোগ্রামে তাদের ব্যবহার করার কারণগুলি নিয়ে আলোচনা করেছি, এবং তাদের সুবিধা এবং অসুবিধাগুলি খুঁজে বের করেছি। আমি এমনকি সি এর মধ্যে সমাবেশে একটি সংক্ষিপ্ত উদাহরণ দিয়েছিলাম। ঠিক একটি রোমাঞ্চকর উন্নয়ন ব্যায়াম নয়, কিন্তু এটি বিন্দুকে চিত্রিত করেছে।

এই নিবন্ধে, আমরা আমাদের সি প্রোগ্রামে বাস্তব কাজ করার জন্য প্রকৃত সিস্টেম কল ব্যবহার করতে যাচ্ছি। প্রথমে, আপনার যদি সিস্টেম কল ব্যবহার করার প্রয়োজন হয় তাহলে আমরা পর্যালোচনা করব, তারপর Sendfile () কল ব্যবহার করে একটি উদাহরণ প্রদান করুন যা নাটকীয়ভাবে ফাইল কপি পারফরম্যান্স উন্নত করতে পারে। অবশেষে, লিনাক্স সিস্টেম কল ব্যবহার করার সময় আমরা কিছু বিষয় মনে রাখব।







যদিও এটি অনিবার্য, আপনি আপনার সি ডেভেলপমেন্ট ক্যারিয়ারের কিছু সময়ে একটি সিস্টেম কল ব্যবহার করবেন, যতক্ষণ না আপনি উচ্চ কর্মক্ষমতা বা একটি বিশেষ ধরনের কার্যকারিতা লক্ষ্য করছেন, প্রধান লিনাক্স বিতরণে অন্তর্ভুক্ত glibc লাইব্রেরি এবং অন্যান্য মৌলিক লাইব্রেরি সংখ্যাগরিষ্ঠের যত্ন নেবে। আপনার চাহিদা.



গ্লিবিসি স্ট্যান্ডার্ড লাইব্রেরি একটি ক্রস-প্ল্যাটফর্ম, ভাল-পরীক্ষিত কাঠামো প্রদান করে যা ফাংশনগুলি সম্পাদন করতে পারে যা অন্যথায় সিস্টেম-নির্দিষ্ট সিস্টেম কলগুলির প্রয়োজন হবে। উদাহরণস্বরূপ, আপনি fscanf (), fread (), getc (), ইত্যাদি দিয়ে একটি ফাইল পড়তে পারেন, অথবা আপনি read () লিনাক্স সিস্টেম কল ব্যবহার করতে পারেন। গ্লিবিসি ফাংশনগুলি আরও বৈশিষ্ট্য সরবরাহ করে (যেমন আরও ভাল ত্রুটি পরিচালনা, ফর্ম্যাট আইও ইত্যাদি) এবং যে কোনও সিস্টেম গ্লিবক সাপোর্টে কাজ করবে।



অন্যদিকে, এমন সময় আছে যখন আপোষহীন কর্মক্ষমতা এবং সঠিক বাস্তবায়ন সমালোচনামূলক। Fread () যে মোড়কটি প্রদান করে তা ওভারহেড যুক্ত করতে চলেছে, এবং যদিও ছোট, পুরোপুরি স্বচ্ছ নয়। উপরন্তু, আপনি মোড়ক প্রদান করে এমন অতিরিক্ত বৈশিষ্ট্যগুলি চান বা প্রয়োজন নাও হতে পারে। সেক্ষেত্রে, আপনি একটি সিস্টেম কল দিয়ে সবচেয়ে ভাল পরিবেশন করেন।





আপনি glibc দ্বারা সমর্থিত নয় এমন ফাংশন সম্পাদনের জন্য সিস্টেম কল ব্যবহার করতে পারেন। যদি আপনার glibc এর কপি আপ টু ডেট থাকে, তাহলে এটি খুব কমই একটি সমস্যা হবে, কিন্তু নতুন কার্নেলের সাথে পুরোনো ডিস্ট্রিবিউশনের জন্য এই টেকনিকের প্রয়োজন হতে পারে।

এখন যেহেতু আপনি অস্বীকৃতি, সতর্কতা এবং সম্ভাব্য পথচলাগুলি পড়েছেন, এখন আসুন কিছু বাস্তব উদাহরণ খতিয়ে দেখি।



আমরা কোন CPU তে আছি?

এমন একটি প্রশ্ন যা বেশিরভাগ প্রোগ্রাম সম্ভবত জিজ্ঞাসা করবে বলে মনে করে না, তবুও একটি বৈধ। এটি একটি সিস্টেম কল এর একটি উদাহরণ যা glibc দিয়ে নকল করা যাবে না এবং একটি glibc মোড়কে আবৃত নয়। এই কোডে, আমরা getcpu () কলটি সরাসরি syscall () ফাংশনের মাধ্যমে কল করব। Syscall ফাংশন নিম্নরূপ কাজ করে:

syscall(SYS_call,arg1,arg2,...);

প্রথম যুক্তি, SYS_call, একটি সংজ্ঞা যা সিস্টেম কলের সংখ্যা উপস্থাপন করে। যখন আপনি sys/syscall.h অন্তর্ভুক্ত করেন, এইগুলি অন্তর্ভুক্ত করা হয়। প্রথম অংশ SYS_ এবং দ্বিতীয় অংশ হল সিস্টেম কল এর নাম।

কলটির জন্য আর্গুমেন্টগুলি উপরে arg1, arg2 এ যায়। কিছু কল আরো যুক্তি প্রয়োজন, এবং তারা তাদের ম্যান পৃষ্ঠা থেকে ক্রম অব্যাহত থাকবে। মনে রাখবেন যে বেশিরভাগ আর্গুমেন্ট, বিশেষ করে রিটার্নের জন্য, ম্যারোক ফাংশনের মাধ্যমে বরাদ্দকৃত চার অ্যারে বা মেমরির জন্য পয়েন্টার প্রয়োজন হবে।

উদাহরণ 1. গ

#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত

intপ্রধান() {

স্বাক্ষরবিহীনসিপিইউ,নোড;

// সিস্টেম কলের মাধ্যমে বর্তমান CPU কোর এবং NUMA নোড পান
// মনে রাখবেন এতে কোন গ্লিবক মোড়ক নেই তাই আমাদের অবশ্যই এটি সরাসরি কল করতে হবে
syscall(SYS_getcpu, &সিপিইউ, &নোড,খালি);

// তথ্য প্রদর্শন
printf (এই প্রোগ্রামটি CPU কোর %u এবং NUMA নোড %u তে চলছে।nn',সিপিইউ,নোড);

প্রত্যাবর্তন 0;

}

কম্পাইল এবং চালানোর জন্য:

gcc উদাহরণ 1। -o উদাহরণ 1
/উদাহরণ 1

আরও আকর্ষণীয় ফলাফলের জন্য, আপনি pthreads লাইব্রেরির মাধ্যমে থ্রেড স্পিন করতে পারেন এবং তারপর আপনার থ্রেডটি কোন প্রসেসরে চলছে তা দেখতে এই ফাংশনটি কল করুন।

Sendfile: সুপেরিয়র পারফরমেন্স

Sendfile সিস্টেম কলের মাধ্যমে কর্মক্ষমতা বৃদ্ধির একটি চমৎকার উদাহরণ প্রদান করে। Sendfile () ফাংশন এক ফাইল বর্ণনাকারী থেকে অন্য ফাইল ডেটা অনুলিপি করে। একাধিক fread () এবং fwrite () ফাংশন ব্যবহার করার পরিবর্তে, Sendfile কার্নেল স্পেসে স্থানান্তর করে, ওভারহেড হ্রাস করে এবং এর ফলে কর্মক্ষমতা বৃদ্ধি পায়।

এই উদাহরণে, আমরা একটি ফাইল থেকে অন্য ফাইলটিতে 64 এমবি ডেটা অনুলিপি করতে যাচ্ছি। একটি পরীক্ষায়, আমরা স্ট্যান্ডার্ড লাইব্রেরিতে স্ট্যান্ডার্ড রিড/রাইটিং পদ্ধতি ব্যবহার করতে যাচ্ছি। অন্যটিতে, আমরা এই তথ্যগুলিকে এক স্থান থেকে অন্য স্থানে বিস্ফোরণের জন্য সিস্টেম কল এবং সেন্ডফিল () কল ব্যবহার করব।

test1.c (glibc)

#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত

#BUFFER_SIZE 67108864 নির্ধারণ করুন
#ডিফাইন BUFFER_1 'বাফার 1'
#ডিফাইন BUFFER_2 'বাফার 2'

intপ্রধান() {

ফাইল*ভুল, *শেষ;

printf ('nTraditionalতিহ্যগত glibc ফাংশন সঙ্গে I/O পরীক্ষা।nn');

// একটি BUFFER_SIZE বাফার নিন।
// বাফারে এর মধ্যে এলোমেলো তথ্য থাকবে কিন্তু আমরা সেদিকে খেয়াল করি না।
printf ('64 এমবি বাফার বরাদ্দ:');
গৃহস্থালি *বাফার= (গৃহস্থালি *) malloc (বাফারের আকার);
printf ('সম্পন্নn');

// fOut এ বাফার লিখুন
printf ('প্রথম বাফারে ডেটা লেখা:');
ভুল= fopen (বাফার_1, 'wb');
fwrite (বাফার, আকার(গৃহস্থালি),বাফারের আকার,ভুল);
fclose (ভুল);
printf ('সম্পন্নn');

printf ('প্রথম ফাইল থেকে দ্বিতীয়টিতে ডেটা অনুলিপি করা:');
শেষ= fopen (বাফার_1, 'আরবি');
ভুল= fopen (বাফার_2, 'wb');
ভাজা (বাফার, আকার(গৃহস্থালি),বাফারের আকার,শেষ);
fwrite (বাফার, আকার(গৃহস্থালি),বাফারের আকার,ভুল);
fclose (শেষ);
fclose (ভুল);
printf ('সম্পন্নn');

printf ('বাফার মুক্ত করা:');
বিনামূল্যে (বাফার);
printf ('সম্পন্নn');

printf ('ফাইল মুছে ফেলা:');
অপসারণ (বাফার_1);
অপসারণ (বাফার_2);
printf ('সম্পন্নn');

প্রত্যাবর্তন 0;

}

test2.c (সিস্টেম কল)

#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত

#BUFFER_SIZE 67108864 নির্ধারণ করুন

intপ্রধান() {

intভুল,শেষ;

printf ('nSendfile () এবং সংশ্লিষ্ট সিস্টেম কলগুলির সাথে I/O পরীক্ষা।nn');

// একটি BUFFER_SIZE বাফার নিন।
// বাফারে এর মধ্যে এলোমেলো তথ্য থাকবে কিন্তু আমরা সেদিকে খেয়াল করি না।
printf ('64 এমবি বাফার বরাদ্দ:');
গৃহস্থালি *বাফার= (গৃহস্থালি *) malloc (বাফারের আকার);
printf ('সম্পন্নn');


// fOut এ বাফার লিখুন
printf ('প্রথম বাফারে ডেটা লেখা:');
ভুল=খোলা('বাফার 1',O_RDONLY);
লিখুন(ভুল, &বাফার,বাফারের আকার);
বন্ধ(ভুল);
printf ('সম্পন্নn');

printf ('প্রথম ফাইল থেকে দ্বিতীয়টিতে ডেটা অনুলিপি করা:');
শেষ=খোলা('বাফার 1',O_RDONLY);
ভুল=খোলা('বাফার 2',O_RDONLY);
ফাইল পাঠান(ভুল,শেষ, 0,বাফারের আকার);
বন্ধ(শেষ);
বন্ধ(ভুল);
printf ('সম্পন্নn');

printf ('বাফার মুক্ত করা:');
বিনামূল্যে (বাফার);
printf ('সম্পন্নn');

printf ('ফাইল মুছে ফেলা:');
আনলিঙ্ক('বাফার 1');
আনলিঙ্ক('বাফার 2');
printf ('সম্পন্নn');

প্রত্যাবর্তন 0;

}

কম্পাইলিং এবং রানিং টেস্ট ১ ও ২

এই উদাহরণগুলি তৈরি করার জন্য, আপনার বিতরণে ইনস্টল করা ডেভেলপমেন্ট সরঞ্জামগুলির প্রয়োজন হবে। ডেবিয়ান এবং উবুন্টুতে, আপনি এটি দিয়ে ইনস্টল করতে পারেন:

উপযুক্তইনস্টলনির্মাণ-প্রয়োজনীয়

তারপর কম্পাইল করুন:

gcctest1.c-অথবাপরীক্ষা 1&& gcctest2.c-অথবাপরীক্ষা 2

উভয় চালাতে এবং কর্মক্ষমতা পরীক্ষা করতে, চালান:

সময়/পরীক্ষা 1&& সময়/পরীক্ষা 2

আপনি এই মত ফলাফল পেতে হবে:

Traditionalতিহ্যগত glibc ফাংশন সঙ্গে I/O পরীক্ষা।

64 এমবি বাফার বরাদ্দ: সম্পন্ন
প্রথম বাফারে ডেটা লেখা: সম্পন্ন
প্রথম ফাইল থেকে দ্বিতীয়টিতে ডেটা অনুলিপি করা: সম্পন্ন
মুক্ত বাফার: সম্পন্ন
ফাইল মুছে ফেলা: সম্পন্ন
বাস্তব 0m0.397s
ব্যবহারকারী 0m0.000s
sys 0m0.203s
Sendfile () এবং সংশ্লিষ্ট সিস্টেম কলগুলির সাথে I/O পরীক্ষা।
64 এমবি বাফার বরাদ্দ: সম্পন্ন
প্রথম বাফারে ডেটা লেখা: সম্পন্ন
প্রথম ফাইল থেকে দ্বিতীয়টিতে ডেটা অনুলিপি করা: সম্পন্ন
মুক্ত বাফার: সম্পন্ন
ফাইল মুছে ফেলা: সম্পন্ন
বাস্তব 0m0.019s
ব্যবহারকারী 0m0.000s
sys 0m0.016s

আপনি দেখতে পাচ্ছেন, যে কোডটি সিস্টেম কল ব্যবহার করে তা glibc সমতুল্যের চেয়ে অনেক দ্রুত চলে।

মনে রাখার মতো ঘটনা

সিস্টেম কলগুলি কর্মক্ষমতা বৃদ্ধি করতে পারে এবং অতিরিক্ত কার্যকারিতা প্রদান করতে পারে, কিন্তু সেগুলি তাদের অসুবিধা ছাড়া নয়। আপনাকে প্ল্যাটফর্ম পোর্টেবিলিটির অভাব এবং কখনও কখনও লাইব্রেরির ফাংশনের তুলনায় কার্যকারিতা হ্রাসের বিরুদ্ধে প্রদত্ত সুবিধাগুলি কল করতে হবে।

কিছু সিস্টেম কল ব্যবহার করার সময়, আপনাকে অবশ্যই লাইব্রেরি ফাংশনগুলির পরিবর্তে সিস্টেম কল থেকে ফিরে আসা সম্পদ ব্যবহার করতে হবে। উদাহরণস্বরূপ, glibc এর fopen (), fread (), fwrite (), এবং fclose () ফাংশনের জন্য ব্যবহৃত FILE স্ট্রাকচার ওপেন () সিস্টেম কল (পূর্ণসংখ্যা হিসাবে ফেরত) থেকে ফাইল বর্ণনাকারী নম্বরের মতো নয়। এগুলো মিশালে সমস্যা হতে পারে।

সাধারণভাবে, লিনাক্স সিস্টেম কলগুলিতে glibc ফাংশনের চেয়ে কম বাম্পার লেন থাকে। যদিও এটি সত্য যে সিস্টেম কলগুলিতে কিছু ত্রুটি পরিচালনা এবং প্রতিবেদন করা থাকে, আপনি একটি গ্লিবক ফাংশন থেকে আরও বিশদ কার্যকারিতা পাবেন।

এবং পরিশেষে, সুরক্ষা সম্পর্কে একটি শব্দ। সিস্টেম সরাসরি কার্নেলের সাথে ইন্টারফেস কল করে। লিনাক্স কার্নেলের ব্যবহারকারীর ভূমি থেকে শেননিগানদের বিরুদ্ধে ব্যাপক সুরক্ষা রয়েছে, কিন্তু অনাবিষ্কৃত বাগ বিদ্যমান। বিশ্বাস করবেন না যে একটি সিস্টেম কল আপনার ইনপুট যাচাই করবে বা আপনাকে নিরাপত্তা সমস্যা থেকে বিচ্ছিন্ন করবে। সিস্টেম কল করার জন্য আপনার দেওয়া ডেটা স্যানিটাইজ করা নিশ্চিত করা বুদ্ধিমানের কাজ। স্বাভাবিকভাবেই, এটি যেকোনো API কলের জন্য ভাল পরামর্শ, কিন্তু কার্নেলের সাথে কাজ করার সময় আপনি সাবধান হতে পারবেন না।

আমি আশা করি আপনি লিনাক্স সিস্টেম কলগুলির দেশে এই গভীর ডুবটি উপভোগ করেছেন। লিনাক্স সিস্টেম কলগুলির সম্পূর্ণ তালিকার জন্য, আমাদের মাস্টার তালিকা দেখুন।