কম্পিউটার

অন্তর্নিহিত থ্রেডিং এবং ভাষা-ভিত্তিক থ্রেড


ইমপ্লিসিট থ্রেডিং

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

অন্তর্ভুক্ত থ্রেডিং থ্রেড পরিচালনা লুকানোর জন্য প্রধানত লাইব্রেরি বা অন্যান্য ভাষা সমর্থন ব্যবহার করা হয়। C.

প্রসঙ্গে সবচেয়ে সাধারণ অন্তর্নিহিত থ্রেডিং লাইব্রেরি হল OpenMP

ওপেনএমপি কম্পাইলার নির্দেশাবলীর একটি সেটের পাশাপাশি C, C++ বা FORTRAN-এ লেখা প্রোগ্রামগুলির জন্য একটি API যা শেয়ার্ড-মেমরি পরিবেশে সমান্তরাল প্রোগ্রামিংয়ের জন্য সমর্থন প্রদান করে। OpenMP সমান্তরাল অঞ্চলগুলিকে কোডের ব্লক হিসাবে চিহ্নিত করে যা সমান্তরালে চলতে পারে। অ্যাপ্লিকেশন ডেভেলপাররা সমান্তরাল অঞ্চলে তাদের কোডে কম্পাইলার নির্দেশাবলী সন্নিবেশ করান, এবং এই নির্দেশাবলী ওপেনএমপি রান-টাইম লাইব্রেরিকে অঞ্চলটিকে সমান্তরালভাবে চালানোর নির্দেশ দেয়। নিম্নলিখিত সি প্রোগ্রামটি সমান্তরাল অঞ্চলের উপরে একটি কম্পাইলার নির্দেশকে চিত্রিত করে যাতে printf() স্টেটমেন্ট রয়েছে:

উদাহরণ

#include <omp.h>
#include <stdio.h>
int main(int argc, char *argv[]){
   /* sequential code */
   #pragma omp parallel{
      printf("I am a parallel region.");
   }
   /* sequential code */
   return 0;
}

আউটপুট

I am a parallel region.

যখন OpenMP নির্দেশের মুখোমুখি হয়

#pragma omp parallel

এটি অনেকগুলি থ্রেড তৈরি করে যা সিস্টেমে কোর প্রক্রিয়াকরণ করছে। এইভাবে, একটি ডুয়াল-কোর সিস্টেমের জন্য, দুটি থ্রেড তৈরি করা হয়, একটি কোয়াড-কোর সিস্টেমের জন্য, চারটি তৈরি করা হয়; এবং তাই ঘোষণা তারপরে সমস্ত থ্রেড একই সাথে সমান্তরাল অঞ্চলটি কার্যকর করে। যখন প্রতিটি থ্রেড সমান্তরাল অঞ্চল থেকে প্রস্থান করে, তখন এটি বন্ধ হয়ে যায়। OpenMP সমান্তরালভাবে কোড অঞ্চলগুলিকে সমান্তরাল লুপগুলি সহ চালানোর জন্য বেশ কয়েকটি অতিরিক্ত নির্দেশ প্রদান করে৷

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

গ্র্যান্ড সেন্ট্রাল ডিসপ্যাচ (GCD)

গ্র্যান্ড সেন্ট্রাল ডিসপ্যাচ (GCD)- অ্যাপলের ম্যাক ওএস এক্স এবং আইওএস অপারেটিং সিস্টেমের জন্য একটি প্রযুক্তি- হল সি ল্যাঙ্গুয়েজ, একটি এপিআই, এবং একটি রান-টাইম লাইব্রেরির এক্সটেনশনের সংমিশ্রণ যা অ্যাপ্লিকেশন ডেভেলপারদের কোডের কিছু অংশে চালানোর অনুমতি দেয়। সমান্তরাল ওপেনএমপির মতো, জিসিডিও থ্রেডিংয়ের বেশিরভাগ বিবরণ পরিচালনা করে। এটি ব্লক হিসাবে পরিচিত C এবং C++ ভাষার এক্সটেনশন সনাক্ত করে। একটি ব্লক হল কাজের একটি স্বয়ংসম্পূর্ণ ইউনিট। এটি একটি ক্যারেট দ্বারা সুনির্দিষ্ট করা হয় একটি জোড়া ধনুর্বন্ধনীর সামনে ঢোকানো { }৷ একটি ব্লকের একটি সাধারণ উদাহরণ নীচে দেখানো হয়েছে -

{
   ˆprintf("This is a block");
}

এটি একটি ডিসপ্যাচ সারিতে রেখে রান-টাইম এক্সিকিউশনের জন্য ব্লক নির্ধারণ করে। যখন GCD একটি সারি থেকে একটি ব্লক সরিয়ে দেয়, তখন এটি যে থ্রেড পুলটি পরিচালনা করে তার থেকে একটি উপলব্ধ থ্রেডে ব্লকটি বরাদ্দ করে। এটি দুটি ধরণের প্রেরণ সারি চিহ্নিত করে:সিরিয়াল এবং সমসাময়িক। ক্রমিক সারিতে স্থাপন করা ব্লকগুলি ফিফো ক্রমানুসারে সরানো হয়। একবার কিউ থেকে একটি ব্লক সরানো হলে, অন্য ব্লক অপসারণের আগে এটি কার্যকরী সম্পন্ন করতে হবে। প্রতিটি প্রক্রিয়ার নিজস্ব সিরিয়াল সারি রয়েছে (প্রধান সারি হিসাবে পরিচিত)। বিকাশকারী অতিরিক্ত সিরিয়াল সারি তৈরি করতে পারে যা নির্দিষ্ট প্রক্রিয়াগুলির জন্য স্থানীয়। ক্রমিক সারিগুলি বেশ কয়েকটি কাজের ক্রমিক সম্পাদন নিশ্চিত করার জন্য দরকারী। একযোগে সারিতে স্থাপন করা ব্লকগুলিও FIFO ক্রমে সরানো হয়, তবে একাধিক ব্লক একই সময়ে সরানো যেতে পারে, এইভাবে একাধিক ব্লক সমান্তরালভাবে চালানোর অনুমতি দেয়। তিনটি সিস্টেম-ওয়াইড সমসাময়িক প্রেরণ সারি আছে, এবং সেগুলি অগ্রাধিকার অনুযায়ী আলাদা করা হয়:নিম্ন, ডিফল্ট এবং উচ্চ। অগ্রাধিকারগুলি ব্লকের আপেক্ষিক গুরুত্বের একটি অনুমান উপস্থাপন করে। খুব সহজভাবে, উচ্চ অগ্রাধিকার সহ ব্লকগুলি উচ্চ অগ্রাধিকার প্রেরণের সারিতে স্থাপন করা উচিত। নিম্নলিখিত কোড সেগমেন্টটি ডিফল্ট-অগ্রাধিকার সমবর্তী সারি প্রাপ্ত করা এবং ডিসপ্যাচ async() ফাংশন ব্যবহার করে সারিতে একটি ব্লক জমা দেওয়ার চিত্র তুলে ধরে:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch async(queue, ˆ{ printf("This is a block."); });

অভ্যন্তরীণভাবে, GCD এর থ্রেড পুল POSIX থ্রেড দিয়ে গঠিত। GCD সক্রিয়ভাবে পুল পরিচালনা করে, যাতে থ্রেডের সংখ্যা বাড়তে এবং অ্যাপ্লিকেশনের চাহিদা এবং সিস্টেমের ক্ষমতা অনুযায়ী সঙ্কুচিত হয়।

অবজেক্ট হিসাবে থ্রেড

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

জাভা থ্রেডস

জাভা একটি থ্রেড বিভাগ এবং একটি রানযোগ্য ইন্টারফেস প্রদান করে যা ব্যবহার করা যেতে পারে। প্রতিটিকে একটি পাবলিক ভ্যাইড রান() কৌশল প্রয়োগ করতে হবে যা থ্রেডের প্রবেশের উদ্দেশ্য নির্ধারণ করে। একবার অবজেক্টের একটি ইন্সট্যান্স বরাদ্দ করা হলে, থ্রেডটি শুরু করা হয় start() টেকনিক ব্যবহার করে। Pthreads-এর মতো, থ্রেডের শুরুটি অ্যাসিঙ্ক্রোনাস, যে কার্য সম্পাদনের সাময়িক বিন্যাস অ-নির্ধারক।

পাইথন থ্রেডস

পাইথন অতিরিক্তভাবে মাল্টিথ্রেডিংয়ের জন্য দুটি প্রক্রিয়া সরবরাহ করে। একটি পদ্ধতি Pthread শৈলীর সাথে তুলনীয়, যেখানেই একটি ফাংশনের নাম একটি লাইব্রেরি পদ্ধতি thread.start_new_thread() এ পাস করা হয়। এই পদ্ধতিটি খুব বেশি এবং থ্রেডটি শুরু হওয়ার পরে যোগদান বা বন্ধ করার নমনীয়তার অভাব রয়েছে। একটি অতিরিক্ত নমনীয় কৌশল হল থ্রেডিং মডিউল ব্যবহার করে থ্রেডিং প্রসারিত করে এমন একটি শ্রেণির রূপরেখা। থ্রেড। প্রায় জাভা পদ্ধতির মতো, ক্যাটাগরিতে রান() পদ্ধতি থাকা উচিত যা থ্রেডের প্রবেশের উদ্দেশ্য দেয়। একবার এই বিভাগ থেকে কোনো বস্তুকে ইনস্ট্যান্টিয়েট করা হলে, এটি স্পষ্টভাবে শুরু করা যাবে এবং পরে যোগদান করা যাবে।

ভাষা ডিজাইন হিসাবে একযোগে

নতুন প্রোগ্রামিং ল্যাঙ্গুয়েজগুলি সরাসরি ভাষা শৈলীতে সমকালীন এক্সিকিউশনের অনুমান তৈরি করে জাতিগত অবস্থা এড়িয়ে গেছে। একটি উদাহরণ হিসাবে, Go চ্যানেলের সাথে একটি তুচ্ছ অন্তর্নিহিত থ্রেডিং কৌশল (গোরুটিন) একত্রিত করে, বার্তা-পাসনের যোগাযোগের একটি সু-সংজ্ঞায়িত শৈলী। মরিচা Pthreads এর মতই একটি নির্দিষ্ট থ্রেডিং পদ্ধতি গ্রহণ করে। যাইহোক, রাস্টের ভয়ঙ্করভাবে শক্তিশালী মেমরি সুরক্ষা রয়েছে যার জন্য সফ্টওয়্যার ইঞ্জিনিয়ারের কোনও অতিরিক্ত কাজের প্রয়োজন নেই৷

গোরুটিন

গো ল্যাঙ্গুয়েজে অন্তর্নিহিত থ্রেডিংয়ের জন্য একটি তুচ্ছ প্রক্রিয়া রয়েছে:একটি কলের আগে go কীওয়ার্ড রাখুন। নতুন থ্রেডটি একটি বার্তা প্রেরণকারী চ্যানেলে একটি অ্যাসোসিয়েশন পাস করা হয়েছে৷ তারপর, সর্বাধিক থ্রেডটি সাফল্যকে বলে :=<-বার্তা, যা চ্যানেলে একটি হস্তক্ষেপ স্ক্যান করে। একবার ব্যবহারকারী সাতটি সঠিক অনুমানে প্রবেশ করলে, কীবোর্ড অডিটর থ্রেড চ্যানেলে লেখে, সর্বাধিক থ্রেডকে অগ্রগতির অনুমতি দেয়।

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

মরিচা সঙ্গতি

আরেকটি ভাষা হল মরিচা যা সাম্প্রতিক বছরগুলিতে তৈরি করা হয়েছে, কেন্দ্রীয় নকশা বৈশিষ্ট্য হিসাবে একযোগে। নিম্নলিখিত উদাহরণটি একটি নতুন থ্রেড তৈরি করতে থ্রেড::স্পোন() এর ব্যবহার চিত্রিত করে, যা পরে এটিতে join() দিয়ে যোগদান করা যেতে পারে। থ্রেডের আর্গুমেন্ট::স্পোন() থেকে শুরু হচ্ছে || এটি একটি বন্ধ হিসাবে পরিচিত, যা একটি বেনামী ফাংশন হিসাবে চিন্তা করা যেতে পারে। অর্থাৎ, এখানে চাইল্ড থ্রেড a এর মান প্রিন্ট করবে।

উদাহরণ

use std::thread;
fn main() {
   /* Initialize a mutable variable a to 7 */
   let mut a = 7;
   /* Spawn a new thread */
   let child_thread = thread::spawn(move || {
      /* Make the thread sleep for one second, then print a */
      a -= 1;
      println!("a = {}", a)
   });
   /* Change a in the main thread and print it */
   a += 1;
   println!("a = {}", a);
   /* Join the thread and print a again */
   child_thread.join();
}

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


  1. কীভাবে একটি মুদ্রণ কাজ বাতিল করবেন এবং প্রিন্টার সারি সাফ করবেন

  2. সমাধান করা হয়েছে:উইন্ডোজ 10 এবং 11 মুদ্রণ সারি মুছে ফেলা যাবে না

  3. পাইথন কিউ এবং ডেক:একটি ধাপে ধাপে গাইড

  4. সি ভাষায় অন্তর্নিহিত এবং স্পষ্ট টাইপ রূপান্তর কি?