এক্সিকিউট () ফাংশন এবং তার পরিবার সম্পর্কে দয়া করে ব্যাখ্যা করুন


102

কি exec()ফাংশন এবং এর পরিবার? এই ফাংশনটি কেন ব্যবহৃত হয় এবং এটি কীভাবে কাজ করে?

যে কেউ এই ফাংশন ব্যাখ্যা করুন।


4
স্টিভেনস আবার পড়ার চেষ্টা করুন, এবং আপনি কী বুঝতে পারছেন না তা স্পষ্ট করে বলুন।
vlabrecque

উত্তর:


250

সরলতার সাথে ইউনিক্সে আপনার প্রক্রিয়া এবং প্রোগ্রামগুলির ধারণা রয়েছে 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

12
এরকম বিশদযুক্ত ব্যাখ্যার জন্য আপনাকে ধন্যবাদ :)
ফয়জান

4
সন্ধান প্রোগ্রামের সাথে শেল রেফারেন্সের জন্য ধন্যবাদ। ঠিক আমার যা বোঝার দরকার ছিল।
ব্যবহারকারী 2

execবর্তমান প্রক্রিয়াটির আইও পুনর্নির্দেশের জন্য ইউটিলিটিটি কেন ব্যবহার করা হয়? এই কনভেনশনটির জন্য যুক্তি ছাড়াই এক্সিকিউটিভ চালানো "নাল" কেস কীভাবে ব্যবহার করতে পেল?
রায়

@ রে, আমি সবসময় এটিকে প্রাকৃতিক বর্ধন হিসাবে ভেবে দেখেছি যদি আপনি execএই প্রক্রিয়াতে বর্তমান প্রোগ্রাম (শেল) কে অন্যটির সাথে প্রতিস্থাপনের উপায় হিসাবে মনে করেন , তবে অন্য প্রোগ্রামটিকে এটির সাথে প্রতিস্থাপনের নির্দিষ্ট করে না আপনি কেবল এটি পরিবর্তন করতে চান না
paxdiablo

"প্রাকৃতিক সম্প্রসারণ" দ্বারা আপনি "জৈবিক বৃদ্ধি" এর ধারায় কিছু বোঝাতে চাইলে আপনি কী বোঝাতে চাই তা আমি দেখতে পাচ্ছি। দেখে মনে হচ্ছে যে প্রোগ্রামটি প্রতিস্থাপনের ক্রিয়াকলাপটি সমর্থন করার জন্য পুনর্নির্দেশটি যুক্ত করা হয়েছে এবং আমি execপ্রোগ্রামটি ছাড়াই ডেকে আনার ক্ষেত্রে অধঃপতনের ক্ষেত্রে এই আচরণটি দেখতে পাচ্ছি । তবে এই দৃশ্যে এটি কিছুটা অদ্ভুত যেহেতু নতুন প্রোগ্রামের জন্য পুনঃনির্দেশের মূল উপযোগিতা - একটি প্রোগ্রাম যা বাস্তবে execউত্সাহিত হবে - অদৃশ্য হয়ে যায় এবং বর্তমান প্রোগ্রামটি পুনর্নির্দেশ করে আপনার একটি কার্যকর শিল্পকর্ম রয়েছে - যা ব্যবহার execবা শুরু হচ্ছে না which যে কোনও উপায়ে - পরিবর্তে
রায়

36

এক্সিকিউটিভ () পরিবারের কার্যাদিগুলির বিভিন্ন আচরণ রয়েছে:

  • l: মূল () তে স্ট্রিংয়ের তালিকা হিসাবে যুক্তিগুলি পাস করা হয়
  • ভি: আর্গুমেন্টগুলি মূল () এ স্ট্রিংয়ের অ্যারে হিসাবে দেওয়া হয়
  • পি: নতুন চলমান প্রোগ্রামের সন্ধানের জন্য পথ / গুলি
  • ই: পরিবেশক কলার দ্বারা নির্দিষ্ট করা যেতে পারে

আপনি এগুলি মিশ্রন করতে পারেন, তাই আপনার কাছে রয়েছে:

  • int এক্সেল (কনস্ট চর * পথ, কনস্ট চর * আরগ, ...);
  • int execlp (কনস্ট চর * ফাইল, কনস্ট চর * আরগ, ...);
  • int এক্সেল (কনস্ট চর * পাথ, কনস্ট চর * আরগ, ..., চর * কনস্ট এনভিপি []);
  • int execv (কনস্ট চর * পথ, চর * কনস্ট আরজিভি []);
  • int execvp (কনস্ট চর * ফাইল, চর * কনস্ট আরজিভি []);
  • int execvpe (কনস্ট চর * ফাইল, চর * কনস্ট আরজিভি [], চর * কনস্ট এনভিপি []);

তাদের সবার জন্য প্রাথমিক যুক্তি হ'ল একটি ফাইলের নাম যা কার্যকর করা উচিত।

আরও তথ্যের জন্য এক্সিকিউট (3) ম্যান পৃষ্ঠা পড়ুন :

man 3 exec  # if you are running a UNIX system

4
মজার বিষয় হল, আপনি execve()নিজের তালিকা থেকে মিস করেছেন, যা পসিক্স দ্বারা সংজ্ঞায়িত হয়েছে, এবং আপনি যুক্ত করেছেন execvpe(), যা পসিক্স দ্বারা সংজ্ঞায়িত হয়নি (বেশিরভাগ historicalতিহাসিক নজির কারণেই; এটি ফাংশনগুলির সেটটি সম্পূর্ণ করে)। অন্যথায়, পরিবারের জন্য নামকরণের কনভেনশন সম্পর্কে সহায়ক ব্যাখ্যা - প্যাক্সিডিয়াব্লো'র একটি কার্যকরী সহায়ক একটি উত্তর যা কার্য সম্পাদন সম্পর্কে আরও ব্যাখ্যা করে।
জনাথন লেফলার

4
এবং, আপনার প্রতিরক্ষাতে, আমি দেখতে পাচ্ছি যে execvpe()(এট আল) এর জন্য লিনাক্স ম্যান পৃষ্ঠাটি তালিকাভুক্ত নয় execve(); এটির নিজস্ব, পৃথক ম্যান পৃষ্ঠা রয়েছে (কমপক্ষে উবুন্টু ১.0.০৪ এলটিএসে) - পার্থক্য হ'ল অন্যান্য exec()পরিবারের ফাংশনগুলি ধারা 3 (ফাংশন) execve()এ তালিকাভুক্ত করা হয়েছে যেখানে বিভাগ 2 (সিস্টেম কল) এ তালিকাবদ্ধ রয়েছে। মূলত, পরিবারের অন্যান্য সমস্ত ক্রিয়াকলাপ কল করার ক্ষেত্রে কার্যকর করা হয় execve()
জোনাথন লেফলার

19

execফাংশন পরিবার আপনার প্রক্রিয়া একটি ভিন্ন প্রোগ্রাম চালানো, পুরাতন প্রোগ্রামটি চলমান ছিল প্রতিস্থাপন করা। অর্থাৎ, আপনি যদি ফোন করেন

execl("/bin/ls", "ls", NULL);

তারপরে lsপ্রোগ্রামটি প্রসেস আইডি, বর্তমান ওয়ার্কিং ডির এবং যে প্রক্রিয়াটি ডেকেছে তার ব্যবহারকারীর / গোষ্ঠী (অ্যাক্সেস রাইটস) দিয়ে কার্যকর করা হয় execl। পরে, মূল প্রোগ্রামটি আর চলছে না।

একটি নতুন প্রক্রিয়া শুরু করতে, forkসিস্টেম কল ব্যবহৃত হয়। আসলটি প্রতিস্থাপন না করেই কোনও প্রোগ্রাম কার্যকর করতে fork, আপনার তখন দরকার exec


আপনাকে ধন্যবাদ যে সত্যই সহায়ক ছিল। আমি বর্তমানে একটি প্রকল্প করছি যা আমাদের এক্সিকিউটিভ () ব্যবহারের প্রয়োজন এবং আপনার বিবরণটি আমার বোধগম্য করে তোলে।
গোধূলি

7

এক্সিকিউটিভ ফাংশন এবং তার পরিবার কী।

execফাংশন পরিবার যেমন একটি ফাইল সঞ্চালনের জন্য ব্যবহৃত সব ফাংশন হয় execl, execlp, execle, execv, এবং execvp.They জন্য সব frontends হয় execveএবং এটি কলিং বিভিন্ন পদ্ধতি প্রদান।

কেন এই ফাংশন ব্যবহার করা হয়

আপনি যখন কোনও ফাইল (প্রোগ্রাম) চালাতে (লঞ্চ) করতে চান তখন এক্সিকিউশন ফাংশনগুলি ব্যবহৃত হয়।

এবং এটি কিভাবে কাজ করে.

আপনি যে প্রবর্তন করেছিলেন তার সাথে বর্তমান প্রক্রিয়া চিত্রটি ওভাররাইট করে তারা কাজ করে। তারা বর্তমানে চলমান প্রক্রিয়াটিকে (সমাপ্ত করে) নতুন প্রক্রিয়া শুরু করেছে যেটি প্রসেস কমান্ড বলে called

আরও তথ্যের জন্য: এই লিঙ্কটি দেখুন


7

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

কমান্ড শেল থেকে।


5

যখন একটি প্রক্রিয়া কাঁটাচামচ ব্যবহার করে (), এটি নিজের একটি সদৃশ অনুলিপি তৈরি করে এবং এই সদৃশগুলি প্রক্রিয়াটির সন্তানের হয়ে ওঠে। কাঁটাচামচ () লিনাক্সে ক্লোন () সিস্টেম কল ব্যবহার করে প্রয়োগ করা হয় যা কার্নেল থেকে দুবার ফিরে আসে।

  • একটি শূন্য-না মান (সন্তানের প্রক্রিয়া ID) পিতামাতাকে ফিরিয়ে দেওয়া হয়।
  • শূন্যের মানটি সন্তানের কাছে ফিরে আসে।
  • লো মেমোরির মতো সমস্যার কারণে যদি শিশুটি সফলভাবে তৈরি না হয় তবে -1 কাঁটাচামচ () এ ফিরে আসে।

আসুন এটি একটি উদাহরণ দিয়ে বুঝতে পারি:

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");

উদাহরণস্বরূপ, আমরা ধরে নিয়েছি যে শিশু প্রক্রিয়াটির মধ্যে এক্সিকিউট () ব্যবহার করা হয় না।

তবে পিসিবি (প্রক্রিয়া নিয়ন্ত্রণ ব্লক) বৈশিষ্ট্যগুলির মধ্যে কিছুতে পিতামাতা এবং সন্তানের মধ্যে পার্থক্য রয়েছে। এইগুলো:

  1. পিআইডি - শিশু এবং পিতামাতার উভয়েরই পৃথক প্রক্রিয়া আইডি রয়েছে।
  2. মুলতুবি সংকেত - সন্তানের পিতামাতার মুলতুবি সংকেত উত্তরাধিকার সূত্রে প্রাপ্ত হয় না। এটি তৈরি করার পরে এটি শিশু প্রক্রিয়াটির জন্য খালি থাকবে।
  3. মেমোরি লকস - শিশুটি তার পিতামাতার মেমরি লকগুলির উত্তরাধিকারী হয় না। মেমরি লকগুলি লকগুলি যা মেমোরি অঞ্চলটিকে লক করতে ব্যবহার করা যেতে পারে এবং তারপরে এই মেমরি অঞ্চলটি ডিস্কে অদলবদল করা যায় না।
  4. রেকর্ড লক্স - শিশু তার পিতামাতার রেকর্ড লকগুলির উত্তরাধিকার সূত্রে পায় না। রেকর্ড লকগুলি কোনও ফাইল ব্লক বা একটি সম্পূর্ণ ফাইলের সাথে সম্পর্কিত।
  5. প্রক্রিয়া সংস্থান ব্যবহার এবং সিপিইউ সময়টি সন্তানের জন্য শূন্যতে সেট করা হয়েছে।
  6. শিশু পিতামাতার কাছ থেকে টাইমারও উত্তরাধিকার সূত্রে পায় না।

তবে বাচ্চার স্মৃতি কী হবে? একটি সন্তানের জন্য নতুন ঠিকানা স্থান তৈরি করা হয়েছে?

উত্তর নেই। কাঁটাচামচ () পরে, পিতামাতা এবং শিশু উভয়ই পিতামাতার মেমরি ঠিকানার স্থান ভাগ করে নেয়। লিনাক্সে, এই ঠিকানা স্থানটি একাধিক পৃষ্ঠায় বিভক্ত। শিশু যখন পিতা-মাতার মেমরির কোনও পৃষ্ঠায় লিখিত হয়, তখন সেই পৃষ্ঠার সদৃশ শিশুর জন্য তৈরি করা হয়। এটি লিখিত অনুলিপি হিসাবেও পরিচিত (পিতা-মাতার পৃষ্ঠাগুলি কেবল তখনই লেখা হয় যখন শিশু এটি লিখবে)।

আসুন একটি উদাহরণ সহ লেখার অনুলিপিটি বুঝতে পারি।

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.

বাবা-মা কেন একটি শিশু প্রক্রিয়াটির জন্য অপেক্ষা করেন?

  1. পিতা-মাতা তার সন্তানের কাছে একটি কার্য নির্ধারণ করতে পারে এবং এটি এর কাজটি শেষ না হওয়া পর্যন্ত অপেক্ষা করতে পারে। তারপরে এটি অন্য কোনও কাজ বহন করতে পারে।
  2. একবার শিশুটি বন্ধ হয়ে যায়, প্রক্রিয়া নিয়ন্ত্রণ ব্লক ব্যতীত সন্তানের সাথে সম্পর্কিত সমস্ত সংস্থানগুলি মুক্তি দেওয়া হয়। এখন, শিশুটি জম্বি অবস্থায় রয়েছে। অপেক্ষা () ব্যবহার করে পিতামাতারা সন্তানের অবস্থা সম্পর্কে জিজ্ঞাসা করতে পারেন এবং তারপরে পিসিবি মুক্ত করার জন্য কার্নেলকে বলতে পারেন। যদি পিতামাতারা অপেক্ষা না করেন তবে শিশুটি জম্বি অবস্থায় থাকবে।

এক্সিকিউটিভ () সিস্টেম কল প্রয়োজনীয় কেন?

কাঁটাচামচ () দিয়ে এক্সিকিউটিভ () ব্যবহার করার দরকার নেই। শিশু যে কোডটি কার্যকর করবে সেই কোডটি পিতামাতার সাথে সম্পর্কিত প্রোগ্রামের মধ্যে থাকলে, এক্সিকিউট () প্রয়োজন হয় না।

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

এটি আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে। আপনার কাছে একটি ওয়েব সার্ভার রয়েছে যা একটি ইনপুট x দিয়েছে যা ক্লায়েন্টগুলিকে 2 ^ x প্রদান করে। প্রতিটি অনুরোধের জন্য, ওয়েব সার্ভার একটি নতুন শিশু তৈরি করে এবং এটি গণনা করতে বলে। আপনি এটি গণনা করতে এবং এক্সিকিউট () ব্যবহার করতে একটি পৃথক প্রোগ্রাম লিখবেন? বা আপনি কেবল পিতামাতার প্রোগ্রামের ভিতরে গণনা কোড লিখবেন?

সাধারণত, একটি প্রক্রিয়া তৈরিতে কাঁটাচামচ (), এক্সিকিউট (), অপেক্ষা () এবং প্রস্থান () কলগুলির সংমিশ্রণ থাকে।


4

exec(3,3p)ফাংশন প্রতিস্থাপন অপরের সাথে বর্তমান প্রক্রিয়া। এটি হ'ল, বর্তমান প্রক্রিয়াটি থেমে যায় এবং এর পরিবর্তে আর একটি চালায়, মূল প্রোগ্রামটির কিছু সংস্থান গ্রহণ করে।


6
বেশ না। এটি বর্তমান প্রক্রিয়া চিত্রটি একটি নতুন প্রক্রিয়া চিত্রের সাথে প্রতিস্থাপন করে । প্রক্রিয়া একই পিড, একই পরিবেশ এবং একই ফাইল বর্ণনাকারী টেবিল সহ একই প্রক্রিয়া। যা বদলেছে তা হ'ল সম্পূর্ণ ভার্চুয়াল মেমরি এবং সিপিইউ স্টেট।
জেরেমিপ

@ জেরেমিপি "একই ফাইল বর্ণনাকারী" এখানে গুরুত্বপূর্ণ ছিল, এটি শেলগুলিতে পুনঃনির্দেশ কীভাবে কাজ করে তা ব্যাখ্যা করে! এক্সিকিউটে সবকিছু ওভাররাইট করে দিলে রিডায়ারেশন কীভাবে কাজ করতে পারে তা নিয়ে আমি ভাবছিলাম! ধন্যবাদ
এফইউডি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.