সি ++ 20-এ কর্টিনগুলি কী কী?


104

কর্টাইন কি কি ?

কীভাবে এটি "সমান্তরালতা 2" বা / এবং "কনকুরেন্সি 2" (চিত্রের নীচে দেখুন) থেকে আলাদা?

নীচের চিত্রটি আইএসওসিপি থেকে প্রাপ্ত।

https://isocpp.org/files/img/wg21-timeline-2017-03.png

এখানে চিত্র বর্ণনা লিখুন


3
উত্তরের জন্য "কোন পদ্ধতিতে কর্টাইনগুলির ধারণা সমান্তরালতা এবং একমত হওয়া থেকে আলাদা ?" - en.wikedia.org/wiki/Curoutine
বেন ভয়েগট


3
করউটিনে একটি খুব ভাল এবং সহজে অনুসরণযোগ্য ইন্ট্রো হ'ল জেমস ম্যাকনেলিসের উপস্থাপনা "সি ++ কর্টাইনগুলির পরিচিতি" (সিপ্পকন ২০১6)।
ফিলসুমুরু

2
পরিশেষে এটিও আচ্ছাদন করা ভাল হবে " C ++ এ কার্টাইনগুলি কী অন্য ভাষাগুলির কর্টিনগুলি এবং পুনরায় শুরুযোগ্য ফাংশনগুলির প্রয়োগ থেকে পৃথক হয়?" (যা উপরোক্ত-লিঙ্কযুক্ত উইকিপিডিয়া নিবন্ধ, ভাষা
বেন ভয়েগট

1
আর কে এই "সি ++ তে কোয়ারানটাইন" পড়েন?
সাহেব ইয়ার

উত্তর:


198

একটি বিমূর্ত স্তরে, Coroutines মৃত্যুদন্ড কার্যকর করার থ্রেড থাকার ধারণার বাইরে ফাঁসির রাজ্য থাকার ধারণাটি বিভক্ত করে।

সিমডি (একক নির্দেশনা একাধিক ডেটা) এর একাধিক "মৃত্যুদণ্ড কার্যকর করার থ্রেড" রয়েছে তবে কেবলমাত্র একটি কার্যকরকরণের অবস্থা (এটি কেবলমাত্র একাধিক ডেটাতে কাজ করে)। তাত্ক্ষণিকভাবে সমান্তরাল অ্যালগোরিদম কিছুটা এরকম, এতে আপনার বিভিন্ন ডেটাতে একটি "প্রোগ্রাম" চালানো থাকে।

থ্রেডিংয়ের একাধিক "এক্সিকিউশন অব থ্রেডস" এবং একাধিক এক্সিকিউশন স্টেট রয়েছে। আপনার একাধিক প্রোগ্রাম এবং একাধিক কার্যকর কার্যকর রয়েছে।

Coroutines একাধিক মৃত্যুদণ্ড রাষ্ট্র আছে, কিন্তু মৃত্যুদন্ড কার্যকর করার একটি থ্রেড এর মালিক নয়। আপনার একটি প্রোগ্রাম রয়েছে, এবং প্রোগ্রামটির স্থিতি রয়েছে তবে এর কার্যকর করার কোনও থ্রেড নেই।


কর্টাইনগুলির সহজতম উদাহরণ হ'ল অন্যান্য ভাষা থেকে প্রাপ্ত জেনারেটর বা গণনাযোগ্য।

সিউডো কোডে:

function Generator() {
  for (i = 0 to 100)
    produce i
}

দ্য Generatorবলা হয়, তারপর প্রথমবার এটা বলা হয় ফেরৎ 0। এর রাজ্যটি স্মরণ করা হয় (কর্টিনগুলি প্রয়োগের সাথে রাষ্ট্র কতটা পরিবর্তিত হয়), এবং পরের বার আপনি যখন এটিকে ডাকবেন তখন এটি যেখানে ছেড়েছিল সেখানেই এটি চালিয়ে যায়। সুতরাং এটি পরের বার 1 ফেরত। তারপরে ২।

অবশেষে এটি লুপের শেষে পৌঁছে যায় এবং ফাংশনটির শেষে পড়ে যায়; কর্টিন সমাপ্ত (এখানে যা ঘটে তা আমরা যে ভাষা নিয়ে কথা বলি তার ভিত্তিতে পরিবর্তিত হয়; পাইথনে এটি একটি ব্যতিক্রম ছুঁড়ে ফেলে)।

করোটাইনগুলি এই ক্ষমতাটি সি ++ এ নিয়ে আসে।

দুটি ধরণের কর্টাইন রয়েছে; স্ট্যাকফুল এবং স্ট্যাকলেস

স্ট্যাকলেস কর্টিন কেবলমাত্র তার রাজ্যে এবং এর কার্যকরকরণের অবস্থানের স্থানীয় ভেরিয়েবলগুলি সঞ্চয় করে।

একটি স্ট্যাকফুল কর্টিন একটি পুরো স্ট্যাক (থ্রেডের মতো) সঞ্চয় করে।

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

কোনও মূল্য উত্পাদন করার প্রক্রিয়াটিকে "ফলন" বলা হয়, কারণ কর্টাইনগুলি সমবায় মাল্টিথ্রেডিংয়ের মতো; আপনি মৃত্যুদণ্ডদানকারীকে কলারের কাছে ফিরিয়ে আনছেন।

বুস্টের স্ট্যাকফুল কোর্টাইনগুলির একটি বাস্তবায়ন রয়েছে; এটি আপনাকে একটি ফাংশন কল করার সুযোগ দেয় আপনার জন্য ফল দেয়। স্ট্যাকফুল কর্টিনগুলি আরও শক্তিশালী, তবে আরও ব্যয়বহুল।


একটি সাধারণ জেনারেটরের চেয়ে কর্টিনগুলি আরও বেশি। আপনি কোনও কর্টিনে কোনও কর্টিনের জন্য অপেক্ষা করতে পারেন, যা আপনাকে দরকারী উপায়ে কর্টিনগুলি রচনা করতে দেয়।

লুপ এবং ফাংশন কলগুলির মতো কর্যটাইনগুলি হ'ল অন্য ধরণের "স্ট্রাকচার্ড গোটো" যা আপনাকে আরও কিছু প্রাকৃতিক উপায়ে নির্দিষ্ট দরকারী নিদর্শনগুলি (রাষ্ট্রযন্ত্রগুলির মতো) প্রকাশ করতে দেয়।


সি ++ তে কার্টাইনগুলির নির্দিষ্ট প্রয়োগটি কিছুটা আকর্ষণীয়।

এর সর্বাধিক প্রাথমিক স্তরে এটি সি ++ এ কয়েকটি কীওয়ার্ড যুক্ত করে: co_return co_await co_yield , কিছু লাইব্রেরির প্রকারের সাথে যা তাদের সাথে কাজ করে।

একটি ফাংশন তার শরীরে এমন একটি থাকার কারণে একটি কর্টিন হয়ে যায়। সুতরাং তাদের ঘোষণা থেকে তারা ফাংশন থেকে পৃথক হয়।

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

সবচেয়ে সহজ কর্টিন একটি জেনারেটর:

generator<int> get_integers( int start=0, int step=1 ) {
  for (int current=start; true; current+= step)
    co_yield current;
}

co_yieldফাংশন সম্পাদন স্থগিত করে, স্টেটে স্টেট সংরক্ষণ করে generator<int>, তারপরে এর currentমাধ্যমে মানটি প্রদান করে generator<int>

ফিরে আসা পূর্ণসংখ্যার উপর লুপ করতে পারেন।

co_awaitইতিমধ্যে আপনাকে একটি কর্টিন অন্যটিতে ছড়িয়ে দিতে দেয় lets আপনি যদি একটি কর্টিনে থাকেন এবং অগ্রগতির আগে আপনার কোনও প্রতীক্ষিত জিনিসের ফলাফল (প্রায়শই একটি কর্টিন) প্রয়োজন হয়, আপনি co_awaitএটির উপর। যদি তারা প্রস্তুত থাকে, আপনি অবিলম্বে এগিয়ে যান; যদি তা না হয় তবে অপেক্ষা করা অপেক্ষারত প্রস্তুত না হওয়া পর্যন্ত আপনি স্থগিত করুন।

std::future<std::expected<std::string>> load_data( std::string resource )
{
  auto handle = co_await open_resouce(resource);
  while( auto line = co_await read_line(handle)) {
    if (std::optional<std::string> r = parse_data_from_line( line ))
       co_return *r;
  }
  co_return std::unexpected( resource_lacks_data(resource) );
}

load_data একটি কর্টিন যা একটি উত্পন্ন করে std::futureনামযুক্ত সংস্থানটি যখন খোলা হয় তখন এবং আমরা অনুরোধকৃত ডেটা খুঁজে পেতাম এমন স্থানে পার্স করার ব্যবস্থা করি।

open_resourceএবং read_lineগুলি সম্ভবত অ্যাসিঙ্ক কর্টিনগুলি যা কোনও ফাইল খুলবে এবং এ থেকে লাইনগুলি পড়বে। co_awaitএর স্থগিত এবং প্রস্তুত রাষ্ট্র সংযোগ load_dataতাদের উন্নতি হয়।

সি ++ কর্টাইনগুলি এর চেয়ে অনেক বেশি নমনীয়, কারণ এগুলি ব্যবহারকারী-স্পেস প্রকারের শীর্ষে ভাষা ন্যূনতম সেট হিসাবে প্রয়োগ করা হয়েছিল। ব্যবহারকারী-স্থানের প্রকারগুলি কার্যকরভাবে কী co_return co_awaitএবং এর co_yield অর্থ নির্ধারণ করে - আমি দেখেছি লোকেরা এটিকে monadic alচ্ছিক এক্সপ্রেশনগুলি বাস্তবায়নের জন্য ব্যবহার করে যাতে co_awaitএকটি খালি onচ্ছিকভাবে খালি স্থিতিকে স্বয়ংক্রিয়ভাবে বাইরের alচ্ছিকভাবে প্রস্তাব দেয়:

modified_optional<int> add( modified_optional<int> a, modified_optional<int> b ) {
  return (co_await a) + (co_await b);
}

পরিবর্তে

std::optional<int> add( std::optional<int> a, std::optional<int> b ) {
  if (!a) return std::nullopt;
  if (!b) return std::nullopt;
  return *a + *b;
}

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

2
আমি অ্যাড-বিকল্পগুলির উদাহরণটি বুঝতে পারি না। std :: alচ্ছিক <int> একটি প্রতীক্ষিত অবজেক্ট নয়।
জীভ ড্যাডসন

1
@ এমর্ড হ্যাঁ এটি 1 টি উপাদান ফেরত দেওয়ার কথা। পলিশিং প্রয়োজন হতে পারে; যদি আমরা একাধিক লাইনের চাই তবে একটি ভিন্ন নিয়ন্ত্রণ প্রবাহের প্রয়োজন।
ইয়াক্ক - অ্যাডাম নেভ্রামুমন্ট

1
@ এলএফ দুঃখিত, থাকার কথা ছিল ;;
ইয়াক্ক - অ্যাডাম নেভ্রামামন্ট

1
এই জাতীয় সরল ক্রিয়াকলাপের জন্য @ এলএফ সম্ভবত কোনও পার্থক্য নেই। তবে আমি যে পার্থক্যটি সাধারণভাবে দেখি তা হ'ল একটি কর্টিন তার শরীরে প্রবেশ / প্রস্থান (এক্সিকিউশন) পয়েন্টটি মনে রাখে যেখানে একটি স্থির ফাংশন প্রতিটি সময় থেকেই শুরু থেকে সম্পাদন শুরু করে। আমার ধারণা "স্থানীয়" ডেটার অবস্থানটি অপ্রাসঙ্গিক।
এভিপি

21

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

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


1

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

একচ্ছত্রতাটি উদ্বেগের পৃথকীকরণের দিকে খুব বেশি মনোনিবেশিত যেখানে একটি উদ্বেগ একটি কাজ যা প্রোগ্রামটি সম্পন্ন করার কথা। উদ্বেগের এই বিচ্ছেদটি বিভিন্ন উপায়ে সম্পন্ন হতে পারে ... সাধারণত কোনও প্রকারের প্রতিনিধি হন। সমাবর্তনের ধারণাটি হ'ল বেশ কয়েকটি প্রক্রিয়া স্বাধীনভাবে চলতে পারে (উদ্বেগের বিভাজন) এবং একটি 'শ্রোতা' এই বিচ্ছিন্ন উদ্বেগগুলির দ্বারা যা কিছু উত্পাদিত হয় সেখানে যেখানে যেতে হবে সেখানে পরিচালিত করবে। এটি একরকম অ্যাসিনক্রোনাস ম্যানেজমেন্টের উপর অত্যন্ত নির্ভরশীল। অ্যাসপেক্ট ওরিয়েন্টেড প্রোগ্রামিং এবং অন্যান্য সহ সম্মতিতে প্রচুর পন্থা রয়েছে। সি # এর 'ডেলিগেট' অপারেটর রয়েছে যা বেশ সুন্দরভাবে কাজ করে।

সমান্তরালতা একমত হওয়ার মতো শোনায় এবং এতে জড়িত থাকতে পারে তবে প্রকৃতপক্ষে এমন অনেকগুলি প্রসেসরের সাথে জড়িত এমন একটি শারীরিক গঠন যা সফ্টওয়্যার দ্বারা আরও কম বা কম সমান্তরাল ফ্যাশনে সাজানো থাকে যা কোডের অংশগুলি বিভিন্ন প্রসেসরে পরিচালিত করতে সক্ষম হয় যেখানে এটি চালিত হবে এবং ফলাফলগুলি ফিরে পাবেন will সিঙ্ক্রোনাস।


9
সংক্ষিপ্তকরণ এবং উদ্বেগের পৃথকীকরণ সম্পূর্ণ সম্পর্কিত নয়। Coroutines স্থগিত রুটিন বিষয়ে তথ্য দিতে হয় না, তারা হয় পুনরারম্ভযোগ্য রুটিন।
বেন ভয়েগট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.