সি ভাষায় সিগন্যাল হ্যান্ডলার কিভাবে ব্যবহার করবেন?

How Use Signal Handlers C Language



এই নিবন্ধে আমরা আপনাকে দেখাতে যাচ্ছি কিভাবে লিনাক্সে সি ভাষা ব্যবহার করে সিগন্যাল হ্যান্ডলার ব্যবহার করতে হয়। কিন্তু প্রথমে আমরা আলোচনা করবো সিগন্যাল কি, কিভাবে এটি কিছু সাধারণ সিগন্যাল তৈরি করবে যা আপনি আপনার প্রোগ্রামে ব্যবহার করতে পারেন এবং তারপর আমরা দেখব কিভাবে প্রোগ্রামটি চলাকালীন বিভিন্ন সিগন্যাল একটি প্রোগ্রাম দ্বারা পরিচালনা করা যায়। সুতরাং শুরু করি.

সংকেত

একটি সংকেত একটি ইভেন্ট যা একটি প্রক্রিয়া বা থ্রেডকে অবহিত করার জন্য তৈরি করা হয় যা কিছু গুরুত্বপূর্ণ পরিস্থিতি এসেছে। যখন একটি প্রক্রিয়া বা থ্রেড একটি সংকেত পেয়েছে, প্রক্রিয়া বা থ্রেড তার কাজ বন্ধ করবে এবং কিছু পদক্ষেপ নেবে। আন্তalপ্রক্রিয়া যোগাযোগের জন্য সংকেত কার্যকর হতে পারে।







স্ট্যান্ডার্ড সিগন্যাল

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



ম্যাক্রো এনএসআইজি সংকেত সংজ্ঞায়িত মোট সংখ্যা। মুল্য এনএসআইজি সংজ্ঞায়িত সংখ্যার মোট সংখ্যার চেয়ে একটি বড় (সমস্ত সংকেত সংখ্যা পরপর বরাদ্দ করা হয়)।



মানক সংকেতগুলি নিম্নরূপ:





সংকেত নাম বর্ণনা
SIGHUP প্রক্রিয়াটি ঝুলিয়ে রাখুন। SIGHUP সিগন্যাল ব্যবহারকারীর টার্মিনালের সংযোগ বিচ্ছিন্নতার প্রতিবেদন করার জন্য ব্যবহার করা হয়, সম্ভবত একটি দূরবর্তী সংযোগ বিচ্ছিন্ন বা বন্ধ হয়ে যাওয়ার কারণে।
SIGINT প্রক্রিয়া বাধাগ্রস্ত করুন। যখন ব্যবহারকারী INTR অক্ষর টাইপ করে (সাধারণত Ctrl + C) SIGINT সিগন্যাল পাঠানো হয়।
SIGQUIT প্রক্রিয়াটি ছেড়ে দিন। যখন ব্যবহারকারী QUIT অক্ষর টাইপ করে (সাধারণত Ctrl + ) SIGQUIT সংকেত পাঠানো হয়।
সীল অবৈধ নির্দেশনা। যখন আবর্জনা বা বিশেষাধিকার নির্দেশনা কার্যকর করার চেষ্টা করা হয়, তখন SIGILL সংকেত তৈরি হয়। এছাড়াও, সিগিল তৈরি করা যেতে পারে যখন স্ট্যাক উপচে পড়ে, অথবা যখন সিস্টেমের সিগন্যাল হ্যান্ডলার চালাতে সমস্যা হয়।
SIGTRAP ট্রেস ফাঁদ। একটি ব্রেকপয়েন্ট নির্দেশ এবং অন্যান্য ফাঁদ নির্দেশ SIGTRAP সংকেত তৈরি করবে। ডিবাগার এই সংকেত ব্যবহার করে।
SIGABRT বাতিল SIGABRT সংকেত উৎপন্ন হয় যখন abort () ফাংশন বলা হয়। এই সংকেতটি একটি ত্রুটি নির্দেশ করে যা প্রোগ্রাম নিজেই সনাক্ত করে এবং abort () ফাংশন কল দ্বারা রিপোর্ট করা হয়।
SIGFPE ফ্লোটিং পয়েন্ট ব্যতিক্রম। যখন একটি মারাত্মক গাণিতিক ত্রুটি ঘটে তখন SIGFPE সংকেত উৎপন্ন হয়।
SIGUSR1 এবং SIGUSR2 SIGUSR1 এবং SIGUSR2 সংকেতগুলি আপনার ইচ্ছামতো ব্যবহার করা যেতে পারে। সহজ ইন্টার-প্রসেস যোগাযোগের জন্য সংকেত গ্রহণকারী প্রোগ্রামে তাদের জন্য একটি সিগন্যাল হ্যান্ডলার লেখা দরকারী।

সিগন্যালের ডিফল্ট অ্যাকশন

প্রতিটি সংকেতের একটি ডিফল্ট অ্যাকশন থাকে, নিচের একটি:

মেয়াদ: প্রক্রিয়াটি বন্ধ হয়ে যাবে।
মূল: প্রক্রিয়াটি শেষ হবে এবং একটি কোর ডাম্প ফাইল তৈরি করবে।
ইগন: প্রক্রিয়াটি সংকেত উপেক্ষা করবে।
থামুন: প্রক্রিয়া বন্ধ হয়ে যাবে।
অ্যাকাউন্ট: থামানো থেকে প্রক্রিয়া চলবে।



হ্যান্ডলার ফাংশন ব্যবহার করে ডিফল্ট অ্যাকশন পরিবর্তন করা যেতে পারে। কিছু সংকেতের ডিফল্ট অ্যাকশন পরিবর্তন করা যাবে না। SIGKILL এবং SIGABRT সিগন্যালের ডিফল্ট ক্রিয়া পরিবর্তন বা উপেক্ষা করা যাবে না।

সিগন্যাল হ্যান্ডলিং

যদি একটি প্রক্রিয়া একটি সংকেত পায়, প্রক্রিয়াটি সেই ধরণের সংকেতের জন্য ক্রিয়াকলাপের পছন্দ করে। প্রক্রিয়াটি সংকেত উপেক্ষা করতে পারে, একটি হ্যান্ডলার ফাংশন নির্দিষ্ট করতে পারে, অথবা সেই ধরনের সংকেতের জন্য ডিফল্ট কর্ম গ্রহণ করতে পারে।

  • যদি সিগন্যালের জন্য নির্দিষ্ট কর্ম উপেক্ষা করা হয়, তাহলে সংকেতটি অবিলম্বে বাতিল করা হয়।
  • প্রোগ্রাম যেমন একটি ফাংশন ব্যবহার করে একটি হ্যান্ডলার ফাংশন নিবন্ধন করতে পারেন সংকেত অথবা sigaction । একে বলা হয় হ্যান্ডলার সিগন্যাল ক্যাচ করে।
  • যদি সিগন্যালটি পরিচালনা না করা হয় বা উপেক্ষা করা না হয় তবে এর ডিফল্ট ক্রিয়া ঘটে।

আমরা সিগন্যাল ব্যবহার করে পরিচালনা করতে পারি সংকেত অথবা sigaction ফাংশন এখানে আমরা দেখি কিভাবে সহজ সংকেত () ফাংশন সিগন্যাল পরিচালনা করার জন্য ব্যবহৃত হয়।

intসংকেত() (intচিহ্ন, অকার্যকর (*ফাংশন)(int))

দ্য সংকেত () কল করবে ফাংশন প্রক্রিয়াটি যদি একটি সংকেত পায় তবে কাজ করুন চিহ্ন । দ্য সংকেত () ফাংশনে একটি পয়েন্টার প্রদান করে ফাংশন যদি সফল হয় বা এটি ত্রুটি ফেরত দেয় এবং অন্যথায় -1।

দ্য ফাংশন পয়েন্টার তিনটি মান থাকতে পারে:

  1. SIG_DFL : এটি সিস্টেম ডিফল্ট ফাংশনের একটি পয়েন্টার SIG_DFL () , ঘোষিত হেডার ফাইল। এটি সিগন্যালের ডিফল্ট অ্যাকশন নিতে ব্যবহৃত হয়।
  2. SIG_IGN : এটি সিস্টেমকে উপেক্ষা করার একটি নির্দেশক ফাংশন SIG_IGN () , ঘোষিত হেডার ফাইল।
  3. ব্যবহারকারী সংজ্ঞায়িত হ্যান্ডলার ফাংশন পয়েন্টার : ব্যবহারকারীর সংজ্ঞায়িত হ্যান্ডলার ফাংশন হল অকার্যকর (*) (int) , মানে রিটার্ন টাইপ অকার্যকর এবং int টাইপের একটি যুক্তি।

বেসিক সিগন্যাল হ্যান্ডলারের উদাহরণ

#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
অকার্যকরsig_handler(intচিহ্ন){

// হ্যান্ডলার ফাংশনের রিটার্ন টাইপ অকার্যকর হওয়া উচিত
printf ('nভিতরে হ্যান্ডলার ফাংশনn');
}

intপ্রধান(){
সংকেত(SIGINT,sig_handler); // রেজিস্টার সিগন্যাল হ্যান্ডলার
জন্য(intআমি=;;আমি++){ //অগণিত চক্র
printf ('%d: প্রধান ফাংশনের ভিতরেn',আমি);
ঘুম(); // 1 সেকেন্ডের জন্য বিলম্ব
}
প্রত্যাবর্তন 0;
}

Example1.c এর আউটপুটের স্ক্রিনশটে, আমরা দেখতে পাচ্ছি যে প্রধান ফাংশনে অসীম লুপ চলছে। যখন ব্যবহারকারী Ctrl+C টাইপ করেন, প্রধান ফাংশন এক্সিকিউশন স্টপ এবং সিগন্যালের হ্যান্ডলার ফাংশন চালু হয়। হ্যান্ডলার ফাংশন শেষ হওয়ার পর, প্রধান ফাংশন এক্সিকিউশন পুনরায় শুরু হয়। যখন ব্যবহারকারীর টাইপ Ctrl+, প্রক্রিয়াটি বন্ধ হয়ে যায়।

সিগন্যালের উদাহরণ উপেক্ষা করুন

#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
intপ্রধান(){
সংকেত(SIGINT,SIG_IGN); // সংকেত উপেক্ষা করার জন্য সংকেত হ্যান্ডলার নিবন্ধন করুন

জন্য(intআমি=;;আমি++){ //অগণিত চক্র
printf ('%d: প্রধান ফাংশনের ভিতরেn',আমি);
ঘুম(); // 1 সেকেন্ডের জন্য বিলম্ব
}
প্রত্যাবর্তন 0;
}

এখানে হ্যান্ডলার ফাংশন হল রেজিস্টার SIG_IGN () সংকেত কর্ম উপেক্ষা করার জন্য ফাংশন। সুতরাং, যখন ব্যবহারকারী Ctrl+C টাইপ করেন, SIGINT সংকেত তৈরি হচ্ছে কিন্তু ক্রিয়াটি উপেক্ষা করা হচ্ছে।

রেজিস্টার সিগন্যাল হ্যান্ডলারের উদাহরণ

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

অকার্যকরsig_handler(intচিহ্ন){
printf ('nভিতরে হ্যান্ডলার ফাংশনn');
সংকেত(SIGINT,SIG_DFL); // ডিফল্ট অ্যাকশনের জন্য সিগন্যাল হ্যান্ডলার পুনরায় নিবন্ধন করুন
}

intপ্রধান(){
সংকেত(SIGINT,sig_handler); // রেজিস্টার সিগন্যাল হ্যান্ডলার
জন্য(intআমি=;;আমি++){ //অগণিত চক্র
printf ('%d: প্রধান ফাংশনের ভিতরেn',আমি);
ঘুম(); // 1 সেকেন্ডের জন্য বিলম্ব
}
প্রত্যাবর্তন 0;
}

Example3.c এর আউটপুটের স্ক্রিনশটে, আমরা দেখতে পাচ্ছি যে যখন ব্যবহারকারী প্রথমবার Ctrl+C টাইপ করেন, তখন হ্যান্ডলার ফাংশন চালু হয়। হ্যান্ডলার ফাংশনে, সিগন্যাল হ্যান্ডলার পুনরায় নিবন্ধন করে SIG_DFL সিগন্যালের ডিফল্ট কর্মের জন্য। যখন ব্যবহারকারী দ্বিতীয়বার Ctrl+C টাইপ করেন, প্রক্রিয়াটি বন্ধ হয়ে যায় যা এর ডিফল্ট ক্রিয়া SIGINT সংকেত

সংকেত প্রেরণ:

একটি প্রক্রিয়া স্পষ্টভাবে নিজেই বা অন্য প্রক্রিয়ায় সংকেত পাঠাতে পারে। সিগন্যাল পাঠানোর জন্য রেইজ () এবং কিল () ফাংশন ব্যবহার করা যেতে পারে। উভয় ফাংশন সিগন্যাল.এইচ হেডার ফাইলে ঘোষণা করা হয়েছে।

int উত্থাপন (intচিহ্ন)

সিগন্যাল পাঠানোর জন্য রাইজ () ফাংশন ব্যবহৃত হয় চিহ্ন কলিং প্রক্রিয়ায় (নিজেই)। এটি সফল হলে শূন্য এবং ব্যর্থ হলে একটি শূন্য মান প্রদান করে।

intহত্যা(pid_t pid, intচিহ্ন)

একটি সংকেত পাঠানোর জন্য ব্যবহৃত কিল ফাংশন চিহ্ন দ্বারা নির্ধারিত একটি প্রক্রিয়া বা প্রক্রিয়া গোষ্ঠীতে পিড

SIGUSR1 সিগন্যাল হ্যান্ডলারের উদাহরণ

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

অকার্যকরsig_handler(intচিহ্ন){
printf ('ইনসাইড হ্যান্ডলার ফাংশনn');
}

intপ্রধান(){
সংকেত(SIGUSR1,sig_handler); // রেজিস্টার সিগন্যাল হ্যান্ডলার
printf ('প্রধান ফাংশনের ভিতরেn');
উত্থাপন (SIGUSR1);
printf ('প্রধান ফাংশনের ভিতরেn');
প্রত্যাবর্তন 0;
}

এখানে, প্রক্রিয়াটি RIGE () ফাংশন ব্যবহার করে নিজেই SIGUSR1 সংকেত পাঠায়।

কিল উদাহরণ প্রোগ্রাম সহ উত্থাপন করুন

#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
অকার্যকরsig_handler(intচিহ্ন){
printf ('ইনসাইড হ্যান্ডলার ফাংশনn');
}

intপ্রধান(){
pid_t pid;
সংকেত(SIGUSR1,sig_handler); // রেজিস্টার সিগন্যাল হ্যান্ডলার
printf ('প্রধান ফাংশনের ভিতরেn');
পিড=getpid(); // নিজেই প্রসেস আইডি
হত্যা(পিড,SIGUSR1); // নিজেই SIGUSR1 পাঠান
printf ('প্রধান ফাংশনের ভিতরেn');
প্রত্যাবর্তন 0;
}

এখানে, প্রক্রিয়া পাঠান SIGUSR1 নিজেই ব্যবহার করে সংকেত হত্যা () ফাংশন getpid () নিজের প্রসেস আইডি পেতে ব্যবহার করা হয়।

পরবর্তী উদাহরণে আমরা দেখব কিভাবে পিতামাতা এবং শিশু প্রক্রিয়াগুলি যোগাযোগ করে (ইন্টার প্রসেস কমিউনিকেশন) ব্যবহার করে হত্যা () এবং সংকেত ফাংশন।

সিগন্যাল দিয়ে পিতামাতার শিশু যোগাযোগ

#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
অকার্যকরsig_handler_parent(intচিহ্ন){
printf ('পিতামাতা: সন্তানের কাছ থেকে একটি প্রতিক্রিয়া সংকেত পেয়েছিn');
}

অকার্যকরsig_handler_child(intচিহ্ন){
printf ('শিশু: পিতামাতার কাছ থেকে একটি সংকেত পেয়েছিn');
ঘুম();
হত্যা(গেটপিড(),SIGUSR1);
}

intপ্রধান(){
pid_t pid;
যদি((পিড=কাঁটা())<0){
printf ('কাঁটা ব্যর্থ হয়েছেn');
প্রস্থান ();
}
/ * শিশু প্রক্রিয়া */
অন্য যদি(পিড==0){
সংকেত(SIGUSR1,sig_handler_child); // রেজিস্টার সিগন্যাল হ্যান্ডলার
printf ('শিশু: সংকেতের জন্য অপেক্ষা করছেn');
বিরতি();
}
/ * মূল প্রক্রিয়া */
অন্য{
সংকেত(SIGUSR1,sig_handler_parent); // রেজিস্টার সিগন্যাল হ্যান্ডলার
ঘুম();
printf ('পিতামাতা: শিশুকে সংকেত পাঠাচ্ছেনn');
হত্যা(পিড,SIGUSR1);
printf (অভিভাবক: প্রতিক্রিয়ার অপেক্ষায়n');
বিরতি();
}
প্রত্যাবর্তন 0;
}

এখানে, কাঁটা () ফাংশন চাইল্ড প্রসেস তৈরি করে এবং চাইল্ড প্রসেসে শূন্য রিটার্ন করে এবং পাইলেন্ট প্রসেসে চাইল্ড প্রসেস আইডি। সুতরাং, পিতামাতা এবং সন্তানের প্রক্রিয়া নির্ধারণের জন্য পিআইডি চেক করা হয়েছে। পিতামাতার প্রক্রিয়ায়, এটি 1 সেকেন্ডের জন্য ঘুমানো হয় যাতে শিশু প্রক্রিয়াটি সিগন্যাল হ্যান্ডলার ফাংশন নিবন্ধন করতে পারে এবং পিতামাতার কাছ থেকে সংকেতের জন্য অপেক্ষা করতে পারে। 1 সেকেন্ডের প্যারেন্ট প্রসেসের পরে পাঠান SIGUSR1 শিশু প্রক্রিয়ায় সংকেত এবং সন্তানের প্রতিক্রিয়া সংকেতের জন্য অপেক্ষা করুন। শিশু প্রক্রিয়ায়, প্রথমে এটি পিতামাতার কাছ থেকে সংকেতের জন্য অপেক্ষা করে এবং যখন সংকেত পাওয়া যায়, তখন হ্যান্ডলার ফাংশন চালু হয়। হ্যান্ডলার ফাংশন থেকে, শিশু প্রক্রিয়া অন্য পাঠায় SIGUSR1 পিতামাতার কাছে সংকেত। এখানে getppid () প্যারেন্ট প্রসেস আইডি পাওয়ার জন্য ফাংশন ব্যবহার করা হয়।

উপসংহার

লিনাক্সে সিগন্যাল একটি বড় বিষয়। এই প্রবন্ধে আমরা দেখেছি কিভাবে খুব বেসিক থেকে সিগন্যাল হ্যান্ডেল করতে হয়, এবং সিগন্যাল কিভাবে উৎপন্ন হয়, কিভাবে একটি প্রক্রিয়া নিজেকে এবং অন্যান্য প্রক্রিয়ায় সিগন্যাল পাঠাতে পারে, কিভাবে ইন্টার-প্রসেস যোগাযোগের জন্য সিগন্যাল ব্যবহার করা যায় সে সম্পর্কেও জ্ঞান লাভ করে।