প্রসেস কনসেপ্ট ও প্রসেস স্টেট
এই পাঠে যা শিখবেন
- প্রসেস ও প্রোগ্রামের মধ্যে সুনির্দিষ্ট পার্থক্য
- পাঁচ-স্টেট প্রসেস মডেল এবং প্রতিটি স্টেটের প্রকৃত অর্থ
- কোন কোন ইভেন্ট একটি প্রসেসকে এক স্টেট থেকে আরেকটিতে নিয়ে যায়, এবং কেন কিছু ট্রানজিশন অবৈধ
- Python দিয়ে একটি বাস্তব স্টেট-মেশিন ইমপ্লিমেন্টেশন যা বৈধ ট্রানজিশন গ্রহণ করে ও অবৈধটি প্রত্যাখ্যান করে
১ · প্রসেস বনাম প্রোগ্রাম
প্রসেসProcessএকটি প্রোগ্রাম এক্সিকিউশনে — একটি সক্রিয় এন্টিটি যার একটি বর্তমান নির্দেশ, CPU রেজিস্টার মান, বরাদ্দকৃত মেমরি ও খোলা ফাইল আছে। হলো একটি প্রোগ্রাম এক্সিকিউশনে। এটি একটি প্রোগ্রামের থেকে সম্পূর্ণ ভিন্ন জিনিস — একটি প্রোগ্রাম হলো ডিস্কে বসে থাকা একটি নিষ্ক্রিয় ফাইল, শুধু নির্দেশাবলীর একটি সংকলন। যখনই এই প্রোগ্রামটি চালানো হয়, OS একটি প্রসেস তৈরি করে — যার একটি সক্রিয় এক্সিকিউশন কনটেক্সট আছে (বর্তমান নির্দেশ কোনটি চলছে, CPU রেজিস্টারের মান, বরাদ্দকৃত মেমরি, খোলা ফাইল)। একই প্রোগ্রাম একাধিকবার চালালে একাধিক আলাদা প্রসেস তৈরি হয় — যেমন একই ব্রাউজার প্রোগ্রামের দুটি আলাদা উইন্ডো দুটি ভিন্ন প্রসেস হতে পারে, প্রতিটির নিজস্ব এক্সিকিউশন কনটেক্সট।
২ · পাঁচ-স্টেট প্রসেস মডেল
একটি প্রসেস তার জীবদ্দশায় নির্দিষ্ট কয়েকটি স্টেটের মধ্য দিয়ে যায় —
প্রসেসটি তৈরি হচ্ছে — এখনও OS-এর রেডি কিউতে ঢোকেনি।
CPU-এর জন্য অপেক্ষমাণ — শিডিউল করা হলে তৎক্ষণাৎ চলতে পারবে।
এই মুহূর্তে CPU-তে এক্সিকিউট হচ্ছে।
কোনো ইভেন্টের (যেমন I/O সম্পন্ন হওয়া) অপেক্ষায় — CPU দিলেও চলতে পারবে না।
এক্সিকিউশন শেষ — প্রসেসটি সমাপ্ত।
৩ · বৈধ ট্রানজিশন
স্টেট পরিবর্তন নির্দিষ্ট ইভেন্ট দ্বারা ট্রিগার হয় — Ready→Running (শিডিউলার প্রসেসটিকে ডিসপ্যাচ করে), Running→Ready (টাইম কোয়ান্টাম শেষ বা প্রিএম্পটেড, M3-এ বিস্তারিত), Running→Waiting (I/O রিকোয়েস্ট করে), Waiting→Ready (I/O সম্পন্ন হয়)। লক্ষণীয় — Waiting থেকে সরাসরি Running-এ যাওয়ার কোনো পথ নেই; একটি প্রসেসকে অবশ্যই প্রথমে Ready-তে ফিরতে হবে এবং আবার শিডিউল হতে হবে। এই কঠোর নিয়মগুলোই নিশ্চিত করে OS সবসময় জানে একটি প্রসেসকে ঠিক কী দেওয়া উচিত (CPU নাকি অপেক্ষা)।
৪ · একটি বাস্তব স্টেট-মেশিন সিমুলেশন
নিচের কোডে একটি transition(current_state, event) ফাংশন বৈধ ট্রানজিশনের একটি টেবিল অনুযায়ী
কাজ করে — একটি প্রসেসকে সম্পূর্ণ জীবনচক্রের মধ্য দিয়ে ট্রেস করে, এবং একটি ইচ্ছাকৃত অবৈধ ট্রানজিশনের চেষ্টাও
দেখায়।
# প্রসেস স্টেট মেশিন -- সিমুলেটেড, বাস্তব কোনো OS প্রসেস নয়
VALID_TRANSITIONS = {
("New", "admit"): "Ready",
("Ready", "dispatch"): "Running",
("Running", "preempt"): "Ready",
("Running", "io_request"): "Waiting",
("Running", "exit"): "Terminated",
("Waiting", "io_complete"): "Ready",
}
def transition(current_state, event):
key = (current_state, event)
if key not in VALID_TRANSITIONS:
raise ValueError(f"অবৈধ ট্রানজিশন: {current_state} -> (event: {event})")
return VALID_TRANSITIONS[key]
# একটি প্রসেসকে ট্রেস করা: New -> Ready -> Running -> Waiting -> Ready -> Running -> Terminated
state = "New"
events = ["admit", "dispatch", "io_request", "io_complete", "dispatch", "exit"]
print("--- একটি প্রসেসের স্টেট ট্রানজিশন ট্রেস ---")
for event in events:
new_state = transition(state, event)
print(f"{state} --({event})--> {new_state}")
state = new_state
print(f"\nচূড়ান্ত অবস্থা: {state}")
# অবৈধ ট্রানজিশনের চেষ্টা: Waiting থেকে সরাসরি Running-এ যাওয়া যায় না
print("\n--- অবৈধ ট্রানজিশনের চেষ্টা ---")
try:
transition("Waiting", "dispatch")
except ValueError as e:
print(f"প্রত্যাখ্যাত: {e}")
VALID_TRANSITIONS ডিকশনারিতে ("Waiting", "dispatch") নামে কোনো
key নেই, তাই transition("Waiting", "dispatch") কল করলে সরাসরি ValueError রেইজ
হয়ে যায় — কোডটি নিজে থেকেই এই অবৈধ পথটি প্রত্যাখ্যান করছে, কোনো হার্ডকোড করা "না" বার্তা প্রিন্ট করা হচ্ছে না।
প্রতিটি প্রসেস যেকোনো মুহূর্তে ঠিক একটি সুনির্দিষ্ট স্টেটে থাকে, এবং সেই স্টেট থেকে শুধু নির্দিষ্ট কয়েকটি পথেই বের হতে পারে। L06 দেখাবে OS ঠিক কীভাবে এই স্টেট তথ্যকে (এবং আরও অনেক কিছু) প্রতিটি প্রসেসের জন্য একটি একক ডেটা স্ট্রাকচারে — Process Control Block (PCB) — সংরক্ষণ করে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ একই প্রোগ্রাম ফাইল থেকে দুটি প্রসেস চালু করলে (যেমন একই এডিটর দুটি আলাদা উইন্ডোতে খোলা), এরা কি একই প্রসেস, নাকি ভিন্ন?
এরা সম্পূর্ণ ভিন্ন দুটি প্রসেস, যদিও একই প্রোগ্রাম ফাইল থেকে তৈরি হয়েছে। প্রতিটির নিজস্ব প্রসেস আইডি, নিজস্ব মেমরি অ্যাড্রেস স্পেস, নিজস্ব CPU রেজিস্টার স্টেট ও নিজস্ব স্টেট (একটি Running, অন্যটি Waiting হতে পারে) থাকে। প্রোগ্রাম ফাইলটি শুধু একটি নিষ্ক্রিয় "নীলনকশা" — একই নীলনকশা থেকে একাধিক স্বাধীন, সক্রিয় প্রসেস তৈরি করা সম্পূর্ণ স্বাভাবিক।
প্র ০২ একটি প্রসেস Ready স্টেটে থাকা মানে কি এটি এখনই কিছু করছে? Waiting স্টেটের সাথে এর মূল পার্থক্য কী?
না, Ready স্টেটে থাকা প্রসেস এই মুহূর্তে কিছুই এক্সিকিউট করছে না — এটি শুধু CPU বরাদ্দের জন্য অপেক্ষা করছে, এবং CPU পেলেই তৎক্ষণাৎ চলতে সক্ষম। Waiting স্টেটের প্রসেস CPU পেলেও চলতে পারবে না, কারণ এটি অন্য কোনো ইভেন্টের (যেমন ডিস্ক থেকে ডেটা আসা) জন্য অপেক্ষা করছে — CPU দেওয়াটাই অর্থহীন যতক্ষণ না সেই ইভেন্টটি ঘটে। এই পার্থক্যই শিডিউলারকে (M3) বলে দেয় কাকে CPU দেওয়া বর্তমানে অর্থবহ।
প্র ০৩
উপরের কোড সেলে events তালিকায় যদি "io_request"-এর পরে সরাসরি "exit" রাখা হতো (I/O সম্পন্ন হওয়ার অপেক্ষা না করেই), কী ঘটত?
তখন প্রসেসটি Waiting স্টেটে থাকা অবস্থায় transition("Waiting", "exit") কল হতো —
VALID_TRANSITIONS ডিকশনারিতে ("Waiting", "exit") নামে কোনো এন্ট্রি নেই (শুধু
("Running", "exit") আছে), তাই এটিও একটি ValueError রেইজ করে প্রত্যাখ্যাত হতো।
এটি বাস্তবতার সাথে সামঞ্জস্যপূর্ণ — একটি প্রসেস সাধারণত Waiting অবস্থা থেকে সরাসরি টার্মিনেট হয় না, আগে
তাকে Ready/Running-এ ফিরে আসতে হয়।
অনুশীলন
-
চিন্তা করুন: আপনার কম্পিউটারে একটি ফাইল ডাউনলোড হচ্ছে এমন একটি প্রোগ্রাম কল্পনা করুন — এটি কোন স্টেটে থাকবে যখন নেটওয়ার্ক ডেটার জন্য অপেক্ষা করছে, আর কোন স্টেটে থাকবে যখন ডাউনলোড হওয়া ডেটা প্রসেস করছে?
নেটওয়ার্ক ডেটার জন্য অপেক্ষা করার সময় প্রোগ্রামটি Waiting/Blocked স্টেটে থাকবে (CPU দিলেও কিছু করতে পারবে না, কারণ এখনও ডেটা আসেনি)। ডেটা এসে গেলে এটি Ready-তে ফিরে আসবে, এবং শিডিউলার CPU দিলে Running স্টেটে গিয়ে সেই ডেটা প্রসেস (যেমন ডিস্কে লেখা) করবে।
-
পরীক্ষা করুন: উপরের কোড সেলে
eventsতালিকার শেষে"dispatch"আরেকবার যোগ করে (Terminated অবস্থার পরে) Run চাপুন — কী হয়?তখন
transition("Terminated", "dispatch")কল হবে।VALID_TRANSITIONS-এ("Terminated", "dispatch")নামে কোনো এন্ট্রি নেই (Terminated থেকে কোনো বৈধ ট্রানজিশনই সংজ্ঞায়িত নেই, যা যুক্তিসঙ্গত — একটি সমাপ্ত প্রসেস আর কোনো স্টেটে যেতে পারে না), তাই একটিValueErrorরেইজ হবে এবং প্রোগ্রামটি (try/except না থাকলে) থেমে যাবে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পরবর্তী পাঠ — PCB ও কনটেক্সট সুইচিং L06 এই স্টেট তথ্য এবং আরও অনেক কিছু OS আসলে কোথায়, কীভাবে সংরক্ষণ করে তা দেখুন।
- CPU শিডিউলিং মডিউল M3 প্রিভিউ Ready→Running ট্রানজিশন ঠিক কীভাবে সিদ্ধান্ত নেওয়া হয় তা M3-এ বিস্তারিত।
- আগের পাঠে ফিরে যান — OS স্ট্রাকচার L04 রিভিশনের জন্য।