কি exec()
ফাংশন এবং এর পরিবার? এই ফাংশনটি কেন ব্যবহৃত হয় এবং এটি কীভাবে কাজ করে?
যে কেউ এই ফাংশন ব্যাখ্যা করুন।
কি exec()
ফাংশন এবং এর পরিবার? এই ফাংশনটি কেন ব্যবহৃত হয় এবং এটি কীভাবে কাজ করে?
যে কেউ এই ফাংশন ব্যাখ্যা করুন।
উত্তর:
সরলতার সাথে ইউনিক্সে আপনার প্রক্রিয়া এবং প্রোগ্রামগুলির ধারণা রয়েছে the প্রক্রিয়া এমন একটি পরিবেশ যা একটি প্রোগ্রাম কার্যকর করে।
ইউএনআইএক্স "এক্সিকিউশন মডেল" এর পেছনের সহজ ধারণাটি হ'ল দুটি কাজ করতে পারেন।
প্রথমটি হ'ল fork()
, যা বর্তমান প্রোগ্রামের ডুপ্লিকেট (বেশিরভাগ) এর রাজ্য সহ একদম নতুন প্রক্রিয়া তৈরি করে। দুটি প্রক্রিয়াগুলির মধ্যে কয়েকটি পার্থক্য রয়েছে যা তাদের এটি নির্ধারণ করতে দেয় যে কোনটি পিতামাতা এবং কোনটি শিশু।
দ্বিতীয়টি হ'ল exec()
, যা বর্তমান প্রক্রিয়ায় প্রোগ্রামটিকে একেবারে নতুন প্রোগ্রামের সাথে প্রতিস্থাপন করে।
এই দুটি সাধারণ অপারেশন থেকে পুরো ইউএনআইএস এক্সিকিউশন মডেলটি তৈরি করা যেতে পারে।
উপরের দিকে আরও কিছু বিশদ যুক্ত করতে:
ইউএনআইএক্সের চেতনা ব্যবহার fork()
এবং exec()
উদাহরণ দিয়ে দেয় যে এটি নতুন প্রক্রিয়া শুরু করার খুব সহজ উপায় সরবরাহ করে।
fork()
কল বর্তমান প্রক্রিয়ার একটি কাছাকাছি ডুপ্লিকেট প্রায় প্রতি উপায় (না অভিন্ন তোলে সবকিছু উপর অনুলিপি করা হয়েছে, উদাহরণস্বরূপ, কিছু বাস্তবায়নের সংস্থান সীমা, কিন্তু ধারণা ঘনিষ্ঠ সম্ভব একটি অনুলিপি তৈরি করতে হয়)। কেবলমাত্র একটি প্রক্রিয়া কল করে fork()
তবে দুটি কলটি কল থেকে ফিরে আসে - উদ্ভট শোনায় তবে এটি সত্যিই বেশ মার্জিত
নতুন প্রক্রিয়া (শিশু বলা হয়) একটি পৃথক প্রক্রিয়া আইডি (পিআইডি) পায় এবং পুরানো প্রক্রিয়ার পিআইডি (পিতামাতাকে) তার প্যারেন্ট পিআইডি (পিপিআইডি) হিসাবে দেয়।
যেহেতু দুটি প্রক্রিয়া এখন একই কোড চলছে, তাদের জানাতে হবে যা কোনটি - রিটার্ন কোডের fork()
এই তথ্যটি সরবরাহ করে - শিশু 0 পায়, পিতামাতারা সন্তানের পিআইডি পান (যদি fork()
ব্যর্থ হয় তবে না শিশু তৈরি করা হয়েছে এবং পিতামাতাকে একটি ত্রুটি কোড পাওয়া যায়)।
এইভাবে, পিতামাতারা সন্তানের পিআইডি জানেন এবং এটির সাথে যোগাযোগ করতে পারেন, হত্যা করতে পারেন, এটির জন্য অপেক্ষা করতে পারেন এবং আরও অনেক কিছু (শিশু সর্বদা একটি কল দিয়ে তার পিতামাতার প্রক্রিয়াটি খুঁজে পেতে পারে getppid()
)।
exec()
কল একটি নতুন প্রোগ্রাম সঙ্গে প্রক্রিয়ার সমগ্র বর্তমান বিষয়বস্তু প্রতিস্থাপন করে। এটি প্রোগ্রামটিকে বর্তমান প্রক্রিয়া জায়গাতে লোড করে এবং এন্ট্রি পয়েন্ট থেকে চালায়।
সুতরাং, fork()
এবং exec()
প্রায়শই ব্যবহার করা হয় একটি বর্তমান প্রক্রিয়া শিশু হিসাবে একটি নতুন প্রোগ্রাম চলমান পেতে ক্রমানুসারে। শেলগুলি সাধারণত যখনই আপনি এই জাতীয় প্রোগ্রাম চালানোর চেষ্টা করেন find
- শেল কাঁটাচামচ, তারপরে শিশু find
প্রোগ্রামটি মেমোরিতে লোড করে , সমস্ত কমান্ড লাইন আর্গুমেন্ট, মান I / O ইত্যাদি সেট করে setting
তবে এগুলি একসাথে ব্যবহার করার দরকার নেই। কোনও প্রোগ্রামকে fork()
নিম্নলিখিতগুলি ছাড়াই কল করা এটি পুরোপুরি গ্রহণযোগ্য exec()
if
এটি ডেমনগুলির জন্য যথেষ্ট ব্যবহৃত হয়েছিল (এবং এখনও রয়েছে) যা কেবলমাত্র একটি টিসিপি পোর্টে শুনেন এবং নির্দিষ্ট অনুরোধটি প্রক্রিয়া করার জন্য নিজের কপিটি কাঁটাচামচ করেন যখন পিতামাতারা শ্রবণে ফিরে যান। এই পরিস্থিতির জন্য, প্রোগ্রামটিতে পিতামাতার এবং সন্তানের কোড উভয়ই রয়েছে ।
একইভাবে, প্রোগ্রাম জানি যে, তারা সমাপ্ত করছি এবং মাত্র অন্য প্রোগ্রাম প্রয়োজন হবে না চালাতে চান fork()
, exec()
এবং তারপর wait()/waitpid()
সন্তানের জন্য। তারা কেবলমাত্র তাদের বর্তমান প্রক্রিয়া স্পেসের সাথে শিশুটিকে সরাসরি লোড করতে পারে exec()
।
কিছু ইউনিক্স বাস্তবায়নের একটি অপ্টিমাইজড রয়েছে fork()
যা তারা অনুলিপিকে অনুলিপি ব্যবহার করে। fork()
প্রোগ্রামটি সেই জায়গাতে কিছু পরিবর্তন করার চেষ্টা না করা পর্যন্ত প্রক্রিয়া স্পেসের অনুলিপিটি বিলম্ব করার একটি কৌশল । এটি কেবলমাত্র সেইসব প্রোগ্রামগুলির জন্যই দরকারী এবং এটির জন্য fork()
নয় exec()
যে তাদের একটি সম্পূর্ণ প্রক্রিয়া স্থান অনুলিপি করতে হবে না। লিনাক্সের অধীনে, fork()
কেবল পৃষ্ঠাগুলির একটি অনুলিপি এবং একটি নতুন টাস্ক স্ট্রাকচার তৈরি করা exec()
হবে, এটি দুটি প্রক্রিয়ার স্মৃতিটিকে "পৃথক" করার মজাদার কাজ করবে।
যদি exec
হয় নিম্নলিখিত নামক fork
(এবং এই কি বেশিরভাগই ঘটে থাকে), যে প্রক্রিয়া স্থান করার জন্য একটি লেখার কারণ এবং এটি তারপর, সন্তানের প্রক্রিয়ার জন্য অনুলিপি করা হয়েছে পরিবর্তন অনুমতি দেওয়া হয় আগে।
লিনাক্সে আরও vfork()
, আরও অনুকূলিতকরণ রয়েছে যা দুটি প্রক্রিয়ার মধ্যে প্রায় সব কিছু ভাগ করে দেয়। যে কারণে, শিশু কি করতে পারি কিছু সীমাবদ্ধতা, ও শিশু কল পর্যন্ত পিতা বা মাতা স্থগিত হয় exec()
বা _exit()
।
দুটি প্রক্রিয়া এমনকি একই স্ট্যাক ভাগ করার কারণে পিতামাতাকে থামাতে হবে (এবং শিশুটিকে বর্তমান ফাংশন থেকে ফিরে আসতে দেওয়া হবে না)। এটি fork()
অবিলম্বে অনুসরণের ক্লাসিক ব্যবহারের ক্ষেত্রে কিছুটা দক্ষ exec()
।
নোট একটি পুরো পরিবারের নেই exec
কল ( execl
, execle
, execve
ইত্যাদি) কিন্তু exec
প্রেক্ষাপটে এখানে তাদের কোন মানে।
নিম্নলিখিত চিত্রটি সেই সাধারণ fork/exec
ক্রিয়াকলাপটি চিত্রিত করে যেখানে bash
শেলটি ls
কমান্ডের সাহায্যে ডিরেক্টরিটি তালিকাবদ্ধ করতে ব্যবহৃত হয় :
+--------+
| pid=7 |
| ppid=4 |
| bash |
+--------+
|
| calls fork
V
+--------+ +--------+
| pid=7 | forks | pid=22 |
| ppid=4 | ----------> | ppid=7 |
| bash | | bash |
+--------+ +--------+
| |
| waits for pid 22 | calls exec to run ls
| V
| +--------+
| | pid=22 |
| | ppid=7 |
| | ls |
V +--------+
+--------+ |
| pid=7 | | exits
| ppid=4 | <---------------+
| bash |
+--------+
|
| continues
V
exec
বর্তমান প্রক্রিয়াটির আইও পুনর্নির্দেশের জন্য ইউটিলিটিটি কেন ব্যবহার করা হয়? এই কনভেনশনটির জন্য যুক্তি ছাড়াই এক্সিকিউটিভ চালানো "নাল" কেস কীভাবে ব্যবহার করতে পেল?
exec
এই প্রক্রিয়াতে বর্তমান প্রোগ্রাম (শেল) কে অন্যটির সাথে প্রতিস্থাপনের উপায় হিসাবে মনে করেন , তবে অন্য প্রোগ্রামটিকে এটির সাথে প্রতিস্থাপনের নির্দিষ্ট করে না আপনি কেবল এটি পরিবর্তন করতে চান না ।
exec
প্রোগ্রামটি ছাড়াই ডেকে আনার ক্ষেত্রে অধঃপতনের ক্ষেত্রে এই আচরণটি দেখতে পাচ্ছি । তবে এই দৃশ্যে এটি কিছুটা অদ্ভুত যেহেতু নতুন প্রোগ্রামের জন্য পুনঃনির্দেশের মূল উপযোগিতা - একটি প্রোগ্রাম যা বাস্তবে exec
উত্সাহিত হবে - অদৃশ্য হয়ে যায় এবং বর্তমান প্রোগ্রামটি পুনর্নির্দেশ করে আপনার একটি কার্যকর শিল্পকর্ম রয়েছে - যা ব্যবহার exec
বা শুরু হচ্ছে না which যে কোনও উপায়ে - পরিবর্তে
এক্সিকিউটিভ () পরিবারের কার্যাদিগুলির বিভিন্ন আচরণ রয়েছে:
আপনি এগুলি মিশ্রন করতে পারেন, তাই আপনার কাছে রয়েছে:
তাদের সবার জন্য প্রাথমিক যুক্তি হ'ল একটি ফাইলের নাম যা কার্যকর করা উচিত।
আরও তথ্যের জন্য এক্সিকিউট (3) ম্যান পৃষ্ঠা পড়ুন :
man 3 exec # if you are running a UNIX system
execve()
নিজের তালিকা থেকে মিস করেছেন, যা পসিক্স দ্বারা সংজ্ঞায়িত হয়েছে, এবং আপনি যুক্ত করেছেন execvpe()
, যা পসিক্স দ্বারা সংজ্ঞায়িত হয়নি (বেশিরভাগ historicalতিহাসিক নজির কারণেই; এটি ফাংশনগুলির সেটটি সম্পূর্ণ করে)। অন্যথায়, পরিবারের জন্য নামকরণের কনভেনশন সম্পর্কে সহায়ক ব্যাখ্যা - প্যাক্সিডিয়াব্লো'র একটি কার্যকরী সহায়ক একটি উত্তর যা কার্য সম্পাদন সম্পর্কে আরও ব্যাখ্যা করে।
execvpe()
(এট আল) এর জন্য লিনাক্স ম্যান পৃষ্ঠাটি তালিকাভুক্ত নয় execve()
; এটির নিজস্ব, পৃথক ম্যান পৃষ্ঠা রয়েছে (কমপক্ষে উবুন্টু ১.0.০৪ এলটিএসে) - পার্থক্য হ'ল অন্যান্য exec()
পরিবারের ফাংশনগুলি ধারা 3 (ফাংশন) execve()
এ তালিকাভুক্ত করা হয়েছে যেখানে বিভাগ 2 (সিস্টেম কল) এ তালিকাবদ্ধ রয়েছে। মূলত, পরিবারের অন্যান্য সমস্ত ক্রিয়াকলাপ কল করার ক্ষেত্রে কার্যকর করা হয় execve()
।
exec
ফাংশন পরিবার আপনার প্রক্রিয়া একটি ভিন্ন প্রোগ্রাম চালানো, পুরাতন প্রোগ্রামটি চলমান ছিল প্রতিস্থাপন করা। অর্থাৎ, আপনি যদি ফোন করেন
execl("/bin/ls", "ls", NULL);
তারপরে ls
প্রোগ্রামটি প্রসেস আইডি, বর্তমান ওয়ার্কিং ডির এবং যে প্রক্রিয়াটি ডেকেছে তার ব্যবহারকারীর / গোষ্ঠী (অ্যাক্সেস রাইটস) দিয়ে কার্যকর করা হয় execl
। পরে, মূল প্রোগ্রামটি আর চলছে না।
একটি নতুন প্রক্রিয়া শুরু করতে, fork
সিস্টেম কল ব্যবহৃত হয়। আসলটি প্রতিস্থাপন না করেই কোনও প্রোগ্রাম কার্যকর করতে fork
, আপনার তখন দরকার exec
।
এক্সিকিউটিভ ফাংশন এবং তার পরিবার কী।
exec
ফাংশন পরিবার যেমন একটি ফাইল সঞ্চালনের জন্য ব্যবহৃত সব ফাংশন হয় execl
, execlp
, execle
, execv
, এবং execvp
.They জন্য সব frontends হয় execve
এবং এটি কলিং বিভিন্ন পদ্ধতি প্রদান।
কেন এই ফাংশন ব্যবহার করা হয়
আপনি যখন কোনও ফাইল (প্রোগ্রাম) চালাতে (লঞ্চ) করতে চান তখন এক্সিকিউশন ফাংশনগুলি ব্যবহৃত হয়।
এবং এটি কিভাবে কাজ করে.
আপনি যে প্রবর্তন করেছিলেন তার সাথে বর্তমান প্রক্রিয়া চিত্রটি ওভাররাইট করে তারা কাজ করে। তারা বর্তমানে চলমান প্রক্রিয়াটিকে (সমাপ্ত করে) নতুন প্রক্রিয়া শুরু করেছে যেটি প্রসেস কমান্ড বলে called
আরও তথ্যের জন্য: এই লিঙ্কটি দেখুন ।
exec
প্রায়শই এটির সাথে একত্রে ব্যবহৃত হয় fork
, যা আমি দেখেছি যে আপনি এটি সম্পর্কে জিজ্ঞাসা করেছিলেন, তাই আমি এটি মনে রেখেই এটি নিয়ে আলোচনা করব।
exec
বর্তমান প্রক্রিয়াটিকে অন্য প্রোগ্রামে পরিণত করে। আপনি যদি ডক্টর হু কে কখনও দেখে থাকেন তবে তার পুনঃজেনার সময়টি এর মতো - তার পুরানো শরীরটি নতুন শরীরের সাথে প্রতিস্থাপিত হয়।
আপনার প্রোগ্রামের সাথে যেভাবে এটি ঘটে exec
এবং ওএস কার্নেল exec
যে প্রোগ্রামটি আর্গুমেন্ট (প্রথম আর্গুমেন্ট) হিসাবে আপনি যে ফাইলটি দিয়ে যাচ্ছেন তা বর্তমান ব্যবহারকারী (প্রক্রিয়াটির ব্যবহারকারী আইডি) দ্বারা নির্বাহযোগ্য কিনা তা পরীক্ষা করার জন্য প্রচুর সংস্থানগুলি পরীক্ষা করে উপার্জন exec
কল) এবং যদি তাই হয় এটা নতুন প্রক্রিয়া এবং কপি একটি ভার্চুয়াল মেমরি বর্তমান প্রক্রিয়ার ভার্চুয়াল মেমরি ম্যাপিং প্রতিস্থাপন argv
এবং envp
ডেটা গৃহীত হয় exec
কল এই নতুন ভার্চুয়াল মেমরি মানচিত্র একটি এলাকা মধ্যে। আরও বেশ কয়েকটি জিনিস এখানেও ঘটতে পারে তবে প্রোগ্রামগুলির জন্য যে ফাইলগুলি exec
খোলা ছিল সেগুলি নতুন প্রোগ্রামের জন্য এখনও খোলা থাকবে এবং তারা একই প্রক্রিয়া আইডিটি ভাগ করে নেবে, তবে যে প্রোগ্রামটি ফোন করেছে exec
তা বন্ধ হবে (এক্সিকিউট ব্যর্থ না হলে)।
কারণ এই এই ভাবে সম্পন্ন করা হয় যে পৃথক হয় চলমান একটি নতুন প্রোগ্রাম ভালো দুটি ধাপে তোমাকে দুটি ধাপে মধ্যে কিছু জিনিস করতে পারেন। সর্বাধিক সাধারণ কাজটি হ'ল এটি নিশ্চিত করা যে নতুন প্রোগ্রামটিতে নির্দিষ্ট ফাইল বর্ণনাকারী হিসাবে নির্দিষ্ট কিছু ফাইল খোলা আছে। (এখানে মনে রাখবেন যে ফাইল বর্ণনাকারীরা এর মতো নন FILE *
, তবে int
কার্নেলটি জানেন এমন মানগুলি)। আপনি এটি করতে পারেন:
int X = open("./output_file.txt", O_WRONLY);
pid_t fk = fork();
if (!fk) { /* in child */
dup2(X, 1); /* fd 1 is standard output,
so this makes standard out refer to the same file as X */
close(X);
/* I'm using execl here rather than exec because
it's easier to type the arguments. */
execl("/bin/echo", "/bin/echo", "hello world");
_exit(127); /* should not get here */
} else if (fk == -1) {
/* An error happened and you should do something about it. */
perror("fork"); /* print an error message */
}
close(X); /* The parent doesn't need this anymore */
এটি চলছে:
/bin/echo "hello world" > ./output_file.txt
কমান্ড শেল থেকে।
যখন একটি প্রক্রিয়া কাঁটাচামচ ব্যবহার করে (), এটি নিজের একটি সদৃশ অনুলিপি তৈরি করে এবং এই সদৃশগুলি প্রক্রিয়াটির সন্তানের হয়ে ওঠে। কাঁটাচামচ () লিনাক্সে ক্লোন () সিস্টেম কল ব্যবহার করে প্রয়োগ করা হয় যা কার্নেল থেকে দুবার ফিরে আসে।
আসুন এটি একটি উদাহরণ দিয়ে বুঝতে পারি:
pid = fork();
// Both child and parent will now start execution from here.
if(pid < 0) {
//child was not created successfully
return 1;
}
else if(pid == 0) {
// This is the child process
// Child process code goes here
}
else {
// Parent process code goes here
}
printf("This is code common to parent and child");
উদাহরণস্বরূপ, আমরা ধরে নিয়েছি যে শিশু প্রক্রিয়াটির মধ্যে এক্সিকিউট () ব্যবহার করা হয় না।
তবে পিসিবি (প্রক্রিয়া নিয়ন্ত্রণ ব্লক) বৈশিষ্ট্যগুলির মধ্যে কিছুতে পিতামাতা এবং সন্তানের মধ্যে পার্থক্য রয়েছে। এইগুলো:
তবে বাচ্চার স্মৃতি কী হবে? একটি সন্তানের জন্য নতুন ঠিকানা স্থান তৈরি করা হয়েছে?
উত্তর নেই। কাঁটাচামচ () পরে, পিতামাতা এবং শিশু উভয়ই পিতামাতার মেমরি ঠিকানার স্থান ভাগ করে নেয়। লিনাক্সে, এই ঠিকানা স্থানটি একাধিক পৃষ্ঠায় বিভক্ত। শিশু যখন পিতা-মাতার মেমরির কোনও পৃষ্ঠায় লিখিত হয়, তখন সেই পৃষ্ঠার সদৃশ শিশুর জন্য তৈরি করা হয়। এটি লিখিত অনুলিপি হিসাবেও পরিচিত (পিতা-মাতার পৃষ্ঠাগুলি কেবল তখনই লেখা হয় যখন শিশু এটি লিখবে)।
আসুন একটি উদাহরণ সহ লেখার অনুলিপিটি বুঝতে পারি।
int x = 2;
pid = fork();
if(pid == 0) {
x = 10;
// child is changing the value of x or writing to a page
// One of the parent stack page will contain this local variable. That page will be duplicated for child and it will store the value 10 in x in duplicated page.
}
else {
x = 4;
}
তবে লেখার অনুলিপি কেন প্রয়োজনীয়?
কাঁটা () - এক্সিকিউট () সংমিশ্রণের মাধ্যমে একটি সাধারণ প্রক্রিয়া তৈরি হয়। আসুন প্রথমে বুঝি এক্সিকিউট () কী করে।
এক্সিকিউট () গ্রুপের ক্রিয়াকলাপ একটি নতুন প্রোগ্রামের সাথে সন্তানের ঠিকানা স্থানকে প্রতিস্থাপন করে। একবার বাচ্চাদের মধ্যে এক্সিকিউট () ডাকা হয়ে গেলে, সন্তানের জন্য পৃথক ঠিকানার স্থান তৈরি করা হবে যা পিতামাতার থেকে সম্পূর্ণ পৃথক।
কাঁটা () এর সাথে যুক্ত লিখন পদ্ধতিতে কোনও অনুলিপি না থাকলে, ডুপ্লিকেট পৃষ্ঠাগুলি সন্তানের জন্য তৈরি করত এবং সমস্ত ডেটা বাচ্চার পৃষ্ঠাতে অনুলিপি করা হত। নতুন মেমরি বরাদ্দ করা এবং ডেটা অনুলিপি করা একটি খুব ব্যয়বহুল প্রক্রিয়া (প্রসেসরের সময় এবং অন্যান্য সিস্টেম সংস্থান লাগে)। আমরা আরও জানি যে বেশিরভাগ ক্ষেত্রে, শিশুটি এক্সিকিউটি () কল করতে চলেছে এবং এটি সন্তানের স্মৃতিটিকে একটি নতুন প্রোগ্রামের সাথে প্রতিস্থাপন করবে। সুতরাং আমরা যে প্রথম অনুলিপিটি করলাম তা যদি নষ্ট না হত তবে লেখার অনুলিপিটি ছিল না।
pid = fork();
if(pid == 0) {
execlp("/bin/ls","ls",NULL);
printf("will this line be printed"); // Think about it
// A new memory space will be created for the child and that memory will contain the "/bin/ls" program(text section), it's stack, data section and heap section
else {
wait(NULL);
// parent is waiting for the child. Once child terminates, parent will get its exit status and can then continue
}
return 1; // Both child and parent will exit with status code 1.
বাবা-মা কেন একটি শিশু প্রক্রিয়াটির জন্য অপেক্ষা করেন?
এক্সিকিউটিভ () সিস্টেম কল প্রয়োজনীয় কেন?
কাঁটাচামচ () দিয়ে এক্সিকিউটিভ () ব্যবহার করার দরকার নেই। শিশু যে কোডটি কার্যকর করবে সেই কোডটি পিতামাতার সাথে সম্পর্কিত প্রোগ্রামের মধ্যে থাকলে, এক্সিকিউট () প্রয়োজন হয় না।
তবে কেসগুলি বিবেচনা করুন যখন শিশুকে একাধিক প্রোগ্রাম চালাতে হয়। শেল প্রোগ্রামের উদাহরণ নেওয়া যাক। এটি ফাইন্ড, এমভি, সিপি, তারিখ ইত্যাদির মতো একাধিক কমান্ডকে সমর্থন করে যেমন কোনও প্রোগ্রামে এই কমান্ডগুলির সাথে যুক্ত প্রোগ্রাম কোড অন্তর্ভুক্ত করা বা শিশুরা যখন প্রয়োজনীয় প্রোগ্রামগুলি মেমরিটিতে লোড করতে পারে সেগুলি ঠিক হবে?
এটি আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে। আপনার কাছে একটি ওয়েব সার্ভার রয়েছে যা একটি ইনপুট x দিয়েছে যা ক্লায়েন্টগুলিকে 2 ^ x প্রদান করে। প্রতিটি অনুরোধের জন্য, ওয়েব সার্ভার একটি নতুন শিশু তৈরি করে এবং এটি গণনা করতে বলে। আপনি এটি গণনা করতে এবং এক্সিকিউট () ব্যবহার করতে একটি পৃথক প্রোগ্রাম লিখবেন? বা আপনি কেবল পিতামাতার প্রোগ্রামের ভিতরে গণনা কোড লিখবেন?
সাধারণত, একটি প্রক্রিয়া তৈরিতে কাঁটাচামচ (), এক্সিকিউট (), অপেক্ষা () এবং প্রস্থান () কলগুলির সংমিশ্রণ থাকে।
exec(3,3p)
ফাংশন প্রতিস্থাপন অপরের সাথে বর্তমান প্রক্রিয়া। এটি হ'ল, বর্তমান প্রক্রিয়াটি থেমে যায় এবং এর পরিবর্তে আর একটি চালায়, মূল প্রোগ্রামটির কিছু সংস্থান গ্রহণ করে।