C++ Coroutines উদাহরণ

C Coroutines Udaharana



Coroutines একটি ভাষা বৈশিষ্ট্য প্রদান করে যা আপনাকে আরও সংগঠিত এবং রৈখিক ফ্যাশনে অ্যাসিঙ্ক্রোনাস কোড লিখতে সক্ষম করে, একটি কাঠামোগত এবং অনুক্রমিক পদ্ধতির প্রচার করে। তারা পুরো থ্রেডটি বন্ধ না করে নির্দিষ্ট পরিস্থিতিতে একটি ফাংশন সম্পাদনকে বিরতি এবং পুনরায় চালু করার একটি প্রক্রিয়া দেয়। I/O ক্রিয়াকলাপগুলির জন্য অপেক্ষা করা যেমন ফাইল থেকে পড়া বা নেটওয়ার্ক কল পাঠানোর মতো কাজগুলি পরিচালনা করার সময় Coroutineগুলি সহায়ক।

কোরোটিনগুলি জেনারেটরের ধারণার উপর ভিত্তি করে যেখানে একটি ফাংশন মান প্রদান করতে পারে এবং পরবর্তীতে সম্পাদন চালিয়ে যাওয়ার জন্য পুনরায় শুরু করা যেতে পারে। Coroutines অ্যাসিঙ্ক্রোনাস অপারেশন পরিচালনা করার জন্য একটি শক্তিশালী টুল প্রদান করে এবং আপনার কোডের সামগ্রিক গুণমানকে ব্যাপকভাবে উন্নত করতে পারে।

Coroutines ব্যবহার

আধুনিক প্রোগ্রামিং-এ বিশেষ করে C++-এর মতো ভাষায় বিভিন্ন কারণে কোরোটিন প্রয়োজন। কোরোটিনগুলি কেন উপকারী তা এখানে কিছু মূল কারণ রয়েছে:







Coroutines অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং একটি মার্জিত সমাধান প্রদান. তারা এমন একটি কোড তৈরি করা সম্ভব করে যা অনুক্রমিক এবং ব্লকিং প্রদর্শিত হয় যা সম্পর্কে যুক্তি এবং বোঝা সহজ। Coroutines থ্রেড ব্লক না করে নির্দিষ্ট পয়েন্টে তাদের মৃত্যুদন্ড স্থগিত করতে পারে, অন্যান্য কাজের সমান্তরাল অপারেশন সক্ষম করে। এই কারণে, সিস্টেম সংস্থানগুলি আরও কার্যকরভাবে ব্যবহার করা যেতে পারে, এবং I/O ক্রিয়াকলাপ জড়িত বা বাহ্যিক ইভেন্টগুলির জন্য অপেক্ষা করা অ্যাপ্লিকেশনগুলিতে প্রতিক্রিয়াশীলতা বৃদ্ধি পায়।



তারা কোড বোঝা এবং বজায় রাখা সহজ করতে পারে. জটিল কলব্যাক চেইন বা স্টেট মেশিনগুলি বাদ দিয়ে, কোরোটিনগুলি কোডটিকে আরও রৈখিক এবং অনুক্রমিক শৈলীতে লিখতে সক্ষম করে। এটি কোড সংগঠনকে উন্নত করে, নেস্টিং হ্রাস করে এবং যুক্তিকে বোঝা সহজ করে তোলে।



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





চলুন C++-এ কোরোটিন বাস্তবায়ন প্রদর্শনের জন্য কিছু উদাহরণ তৈরি করি।

উদাহরণ 1: মৌলিক কোরোটিন

মৌলিক কোরোটিন উদাহরণ নিম্নলিখিত প্রদান করা হয়:



# অন্তর্ভুক্ত করুন

#অন্তর্ভুক্ত

গঠন এই কোরাউট {

গঠন প্রতিশ্রুতি_টাইপ {

ThisCorout get_return_object ( ) { ফিরে { } ; }

std :: suspend_never প্রাথমিক_সাসপেন্ড ( ) { ফিরে { } ; }

std :: suspend_never চূড়ান্ত_সাসপেন্ড ( ) ছাড়া { ফিরে { } ; }

অকার্যকর unhandled_exception ( ) { }

অকার্যকর রিটার্ন_অকার্যকর ( ) { }

} ;

bool await_ready ( ) { ফিরে মিথ্যা ; }

অকার্যকর await_sspend ( std :: coroutine_handle <> ) { }

অকার্যকর await_resume ( ) { std :: cout << 'করোটিন আবার শুরু হয়েছে।' << std :: endl ; }

} ;

এই কোরউট foo ( ) {

std :: cout << 'করোটিন শুরু হয়েছে।' << std :: endl ;

co_await std :: স্থগিত_সর্বদা { } ;

সহ_প্রত্যাবর্তন ;

}

int প্রধান ( ) {

স্বয়ংক্রিয় cr = foo ( ) ;

std :: cout << 'করোটিন তৈরি করা হয়েছে।' << std :: endl ;

cr await_resume ( ) ;

std :: cout << 'করোটিন সমাপ্ত।' << std :: endl ;

ফিরে 0 ;

}

আসুন পূর্বে প্রদত্ত কোডের মধ্য দিয়ে যান এবং এটি বিস্তারিতভাবে ব্যাখ্যা করি:

প্রয়োজনীয় শিরোনাম ফাইলগুলি অন্তর্ভুক্ত করার পরে, আমরা 'ThisCorout' struct সংজ্ঞায়িত করি যা একটি coroutine প্রতিনিধিত্ব করে। 'ThisCorout' এর ভিতরে, আরেকটি স্ট্রাকট যা 'প্রতিশ্রুতি_টাইপ' সংজ্ঞায়িত করা হয়েছে যেটি করোটিন প্রতিশ্রুতি পরিচালনা করে। এই স্ট্রাকট বিভিন্ন ফাংশন প্রদান করে যা কোরোটিন যন্ত্রপাতি দ্বারা প্রয়োজনীয়।

বন্ধনীর ভিতরে, আমরা get_return_object() ফাংশনটি ব্যবহার করি। এটি coroutine অবজেক্ট নিজেই ফেরত দেয়। এই উদাহরণে, এটি একটি খালি 'ThisCorout' অবজেক্ট ফেরত দেয়। তারপরে, প্রাথমিক_সাসপেন্ড() ফাংশনটি চালু করা হয় যা coroutine প্রথম শুরু হলে আচরণ নির্ধারণ করে। std::suspend_never এর মানে হল যে coroutine প্রাথমিকভাবে স্থগিত করা উচিত নয়।

এর পরে, আমাদের কাছে final_suspend() ফাংশন রয়েছে যা কোরোটিন শেষ হওয়ার সময় আচরণ নির্ধারণ করে। std::suspend_never এর মানে হল যে coroutine চূড়ান্ত হওয়ার আগে স্থগিত করা উচিত নয়।

যদি একটি coroutine একটি ব্যতিক্রম নিক্ষেপ করে, unhandled_exception() পদ্ধতিটি চালু করা হয়। এই উদাহরণে, এটি একটি খালি ফাংশন, তবে আপনি প্রয়োজন অনুসারে ব্যতিক্রমগুলি পরিচালনা করতে পারেন। যখন coroutine কোনো মান না দিয়েই সমাপ্ত হয়, তখন return_void() পদ্ধতিটি চালু করা হয়। এই ক্ষেত্রে, এটি একটি খালি ফাংশন।

আমরা 'ThisCorout'-এর মধ্যে তিনটি সদস্য ফাংশনও সংজ্ঞায়িত করি। await_ready() ফাংশনটি পরীক্ষা করার জন্য কল করা হয় যে কোরোটিনটি এক্সিকিউশন পুনরায় শুরু করার জন্য প্রস্তুত কিনা। এই উদাহরণে, এটি সর্বদা মিথ্যা ফেরত দেয় যা নির্দেশ করে যে কোরোটিন অবিলম্বে পুনরায় শুরু করার জন্য প্রস্তুত নয়। যখন coroutine স্থগিত করা যাচ্ছে, পদ্ধতিটি await_suspend() বলা হয়। এখানে, এটি একটি খালি ফাংশন যার মানে কোন সাসপেনশনের প্রয়োজন নেই। প্রোগ্রামটি await_resume() কে কল করে যখন কোরোটিন সাসপেনশনের পরে পুনরায় শুরু করা হয়। এটি কেবল একটি বার্তা আউটপুট করে যা বলে যে করোটিন পুনরায় শুরু করা হয়েছে।

কোডের পরবর্তী লাইন foo() coroutine ফাংশন সংজ্ঞায়িত করে। foo() এর ভিতরে, আমরা একটি বার্তা প্রিন্ট করে শুরু করি যা বলে যে কোরোটিন শুরু হয়েছে। তারপর, co_await std::suspend_always{} coroutine স্থগিত করতে ব্যবহার করা হয় এবং নির্দেশ করে যে এটি পরবর্তী সময়ে আবার চালু করা যেতে পারে। কো_রিটার্ন স্টেটমেন্টটি কোনো মান ফেরত না দিয়েই করুটিন শেষ করতে ব্যবহৃত হয়।

main() ফাংশনে, আমরা foo() কল করে 'ThisCorout' টাইপের একটি বস্তু 'cr' তৈরি করি। এটি করোটিন তৈরি করে এবং শুরু করে। তারপরে, একটি বার্তা যা বলে যে করোটিন তৈরি করা হয়েছে মুদ্রিত হয়। এর পরে, আমরা 'cr' coroutine অবজেক্টে await_resume() কে এর কার্য সম্পাদন পুনরায় শুরু করার জন্য কল করি। await_resume() এর ভিতরে “The Coroutine is resumed” বার্তাটি প্রিন্ট করা হয়েছে। অবশেষে, আমরা একটি বার্তা প্রদর্শন করি যাতে বলা হয় যে প্রোগ্রামটি শেষ হওয়ার আগে করোটিন সম্পূর্ণ হয়ে গেছে।

আপনি যখন এই প্রোগ্রামটি চালান, আউটপুটটি নিম্নরূপ:

উদাহরণ 2: পরামিতি এবং ফলন সহ করুটিন

এখন, এই দৃষ্টান্তের জন্য, আমরা একটি কোড প্রদান করি যা সংখ্যার ক্রম তৈরি করার জন্য একটি জেনারেটরের মতো আচরণ তৈরি করতে পরামিতি সহ coroutines এর ব্যবহার এবং C++ তে ফলন প্রদর্শন করে।

# অন্তর্ভুক্ত করুন

#অন্তর্ভুক্ত

# অন্তর্ভুক্ত <ভেক্টর>

গঠন নিউকরোটিন {

গঠন p_type {

std :: ভেক্টর < int > মান ;

NEWCorutine get_return_object ( ) { ফিরে { } ; }

std :: স্থগিত_সর্বদা প্রাথমিক_সাসপেন্ড ( ) { ফিরে { } ; }

std :: স্থগিত_সর্বদা চূড়ান্ত_সাসপেন্ড ( ) ছাড়া { ফিরে { } ; }

অকার্যকর unhandled_exception ( ) { }

অকার্যকর রিটার্ন_অকার্যকর ( ) { }

std :: স্থগিত_সর্বদা ফলন_মূল্য ( int মান ) {

মান ফেরত পাঠাও ( মান ) ;

ফিরে { } ;

}

} ;

std :: ভেক্টর < int > মান ;

গঠন পুনরাবৃত্তিকারী {

std :: coroutine_handle <> কোরাস_হ্যান্ডেল ;

bool অপারেটর != ( const পুনরাবৃত্তিকারী এবং অন্যান্য ) const { ফিরে কোরাস_হ্যান্ডেল != অন্যান্য কোরাস_হ্যান্ডেল ; }

পুনরাবৃত্তিকারী এবং অপারেটর ++ ( ) { কোরাস_হ্যান্ডেল জীবনবৃত্তান্ত ( ) ; ফিরে * এই ; }

int অপারেটর * ( ) const { ফিরে কোরাস_হ্যান্ডেল প্রতিশ্রুতি ( ) . মান [ 0 ] ; }

} ;

পুনরাবৃত্তিকারী শুরু ( ) { ফিরে পুনরাবৃত্তিকারী { std :: coroutine_handle < p_type >:: থেকে_প্রতিশ্রুতি ( প্রতিশ্রুতি ( ) ) } ; }

পুনরাবৃত্তিকারী শেষ ( ) { ফিরে পুনরাবৃত্তিকারী { nullptr } ; }

std :: coroutine_handle < p_type > প্রতিশ্রুতি ( ) { ফিরে
std :: coroutine_handle < p_type >:: থেকে_প্রতিশ্রুতি ( * এই ) ; }

} ;

NEWCorutine জেনারেট নম্বর ( ) {

co_yield 5 ;

co_yield 6 ;

co_yield 7 ;

}

int প্রধান ( ) {

NEWCorutine nc = সংখ্যা তৈরি করুন ( ) ;

জন্য ( int মান : nc ) {

std :: cout << মান << '' ;

}

std :: cout << std :: endl ;

ফিরে 0 ;

}

পূর্ববর্তী কোডে, NEWCoroutine struct একটি coroutine-ভিত্তিক জেনারেটর প্রতিনিধিত্ব করে। এটিতে একটি নেস্টেড 'p_type' স্ট্রাকট রয়েছে যা করটিনের জন্য প্রতিশ্রুতি টাইপ হিসাবে কাজ করে। p_type struct সেই ফাংশনগুলিকে সংজ্ঞায়িত করে যা coroutine মেশিনের জন্য প্রয়োজনীয় যেমন get_return_object(), initial_suspend(), final_suspend(), unhandled_exception(), এবং return_void()। p_type struct-এ yield_value(int value) ফাংশনও রয়েছে যা coroutine থেকে মান আনতে ব্যবহৃত হয়। এটি মান ভেক্টরে প্রদত্ত মান যোগ করে।

NEWCoroutine struct-এর মধ্যে std::vector সদস্য ভেরিয়েবল রয়েছে যাকে 'মান' বলা হয় যা উৎপন্ন মানগুলিকে উপস্থাপন করে। NEWCoroutine-এর ভিতরে, একটি নেস্টেড স্ট্রাকট ইটারেটর রয়েছে যা জেনারেট করা মানগুলির উপর পুনরাবৃত্তি করতে দেয়। এটি একটি coro_handle ধারণ করে যা coroutine-এর একটি হ্যান্ডেল এবং অপারেটরকে সংজ্ঞায়িত করে যেমন !=, ++, এবং * পুনরাবৃত্তির জন্য।

আমরা p_type প্রতিশ্রুতি থেকে coro_handle প্রাপ্ত করে coroutine এর শুরুতে একটি পুনরাবৃত্তিকারী তৈরি করতে begin() ফাংশন ব্যবহার করি। যেখানে end() ফাংশন একটি ইটরেটর তৈরি করে যা করটিনের শেষকে প্রতিনিধিত্ব করে এবং একটি nullptr coro_handle দিয়ে তৈরি করা হয়। এর পরে, প্রতিশ্রুতি () ফাংশনটি p_type প্রতিশ্রুতি থেকে একটি coroutine_handle তৈরি করে প্রতিশ্রুতি টাইপ ফেরত দিতে ব্যবহার করা হয়। generateNumbers() ফাংশন হল একটি coroutine যেটি co_yield কীওয়ার্ড ব্যবহার করে তিনটি মান – 5, 6, এবং 7 – প্রদান করে।

main() ফাংশনে, generateNumbers() coroutine ব্যবহার করে 'nc' নামের NEWCoroutine-এর একটি উদাহরণ তৈরি করা হয়েছে। এটি করোটিনকে আরম্ভ করে এবং এর অবস্থা ক্যাপচার করে। একটি রেঞ্জ-ভিত্তিক 'for' লুপ ব্যবহার করা হয় 'nc' এর মানগুলির উপর পুনরাবৃত্তি করতে এবং প্রতিটি মান প্রিন্ট করা হয় যা std::cout ব্যবহার করে একটি স্পেস দ্বারা পৃথক করা হয়।

উত্পন্ন আউটপুট নিম্নরূপ:

উপসংহার

এই নিবন্ধটি C++ এ কোরোটিনের ব্যবহার প্রদর্শন করে। আমরা দুটি উদাহরণ আলোচনা করেছি। প্রথম দৃষ্টান্তের জন্য, কোরোটিন ফাংশন ব্যবহার করে একটি C++ প্রোগ্রামে মৌলিক করটিন তৈরি করা হয়। যখন দ্বিতীয় প্রদর্শনটি প্যারামিটার সহ coroutines ব্যবহার করে এবং সংখ্যার একটি ক্রম তৈরি করার জন্য একটি জেনারেটরের মতো আচরণ তৈরি করার মাধ্যমে বাহিত হয়েছিল।