Coroutine বনাম ধারাবাহিকতা বনাম জেনারেটর


147

একটি করোটিন এবং একটি ধারাবাহিকতা এবং একটি জেনারেটরের মধ্যে পার্থক্য কী?


2
আমি ভাবছি যদি কর্টাইন এবং ধারাবাহিকতা কার্যকরভাবে সমান হয়। আমি জানি যে ধারাবাহিকতায় কর্টিনগুলি মডেল করা সম্ভব, তবে ধারাবাহিকতা কঠোরভাবে আরও শক্তিশালী হওয়ার কারণে এটি কি কর্টিনগুলির সাথে ধারাবাহিকতাগুলি মডেল করা সম্ভব?
স্পষ্টভাবে

উত্তর:


127

আমি জেনারেটর দিয়ে শুরু করব, তারা দেখতে পাবে যে এগুলি সহজতম ঘটনা। @ জভোলকভ যেমন উল্লেখ করেছেন, এগুলি এমন ফাংশন / অবজেক্টস যা বারবার ফিরে না এসে ডাকা যেতে পারে, তবে যখন ডাকা হয় তখন একটি মূল্য ফিরে আসবে (ফলন দেওয়া) এবং তার কার্যকরকরণ স্থগিত করে। যখন তাদের আবার ডাকা হবে, তারা শেষ হবে যেখানে তারা শেষ পর্যন্ত কার্যকর করা স্থগিত করেছিল এবং তাদের কাজটি আবার করবে।

একটি জেনারেটর মূলত একটি কাটা ডাউন (অ্যাসিমেট্রিক) করোটিন। কর্টিন এবং জেনারেটরের মধ্যে পার্থক্য হ'ল প্রাথমিকভাবে বলা হওয়ার পরে কোনও কর্টিন যুক্তি গ্রহণ করতে পারে, যেখানে জেনারেটর পারে না।

আপনি যেখানে কর্টিন ব্যবহার করেন তার একটি তুচ্ছ উদাহরণটি উপস্থিত করা কিছুটা কঠিন, তবে এখানে আমার সেরা চেষ্টা। এটি (তৈরি) উদাহরণস্বরূপ পাইথন কোডটি ধরুন।

def my_coroutine_body(*args):
    while True:
        # Do some funky stuff
        *args = yield value_im_returning
        # Do some more funky stuff

my_coro = make_coroutine(my_coroutine_body)

x = 0
while True:
   # The coroutine does some funky stuff to x, and returns a new value.
   x = my_coro(x)
   print x

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

(আমি প্রতিসাম্য এবং অ্যাসিমেট্রিক করোটিনগুলির মধ্যে পার্থক্যটি ব্রাশ করতে যাচ্ছি it এগুলি সমতুল্য বলে মনে হয় যথেষ্ট, আপনি এক থেকে অন্যটিতে রূপান্তর করতে পারেন, এবং অ্যাসিমেট্রিক কর্টিনস - যা সবচেয়ে জেনারেটরের মতো - সেগুলি হ'ল) বুঝতে সহজতর। আমি কীভাবে পাইথনে অ্যাসিমেট্রিক কর্টিনগুলি প্রয়োগ করতে পারে তা আমি রূপরেখা দিয়েছিলাম)

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

বলুন পাইথনের একটি ফাংশন বলা হয়েছিল callcc(), এবং এই ফাংশনটিতে দুটি আর্গুমেন্ট নিয়েছিল, প্রথমটি একটি ফাংশন এবং দ্বিতীয়টি এটি দিয়ে কল করার জন্য যুক্তির একটি তালিকা। এই ফাংশনটিতে কেবলমাত্র সীমাবদ্ধতাটি হ'ল এটি শেষ যুক্তিটি গ্রহণ করবে এটি একটি ফাংশন হবে (যা আমাদের বর্তমান ধারাবাহিকতা হবে)।

def foo(x, y, cc):
   cc(max(x, y))

biggest = callcc(foo, [23, 42])
print biggest

কি ঘটতে পারে যে callcc()কল আবর্তিত হবে foo()বর্তমান ধারাবাহিকতা (সঙ্গে cc), যে, প্রোগ্রামে বিন্দু একটি রেফারেন্স যা callcc()ডাকা হয়। যখন foo()বর্তমান ধারাবাহিকতা ডাকে, এটি মূলত একই callcc()মান হিসাবে আপনি বর্তমানের ধারাবাহিকতাটিকে যে মানটির সাথে কল করছেন তার সাথে ফিরে আসতে বলার মত এবং যখন এটি হয় তখন এটি স্ট্যাকটি ফিরিয়ে দেয় যেখানে বর্তমান ধারাবাহিকতাটি তৈরি হয়েছিল, যেমন, আপনি যখন ফোন করেছিলেন callcc()

এই সমস্তগুলির ফলাফলটি হবে যে আমাদের অনুমানক পাইথন রূপটি মুদ্রণ করবে '42'

আমি আশা করি এটি সাহায্য করে এবং আমি নিশ্চিত যে আমার ব্যাখ্যাটি কিছুটা উন্নত হতে পারে!


6
একটি নিট: সীমাবদ্ধ ধারাবাহিকতাগুলি হ'ল ফাংশন, তবে অনির্ধারিত ধারাবাহিকতাগুলি হ'ল
ফ্রাঙ্ক শিয়েরার

2
এটা একটা ভাল দিক. এটি বলেছিল, বেশিরভাগ ব্যবহারিক প্রয়োগগুলিতে, যখন লোকেরা 'ধারাবাহিকতা' বলে, তারা আংশিক / বিস্মৃত ধারাবাহিকতার কথা বলছে। বিভিন্ন ধরণের ধারাবাহিকতা এনে দেওয়া ব্যাখ্যাটিকে কিছুটা হতাশ করে তুলেছে।
কিথ গোগান

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

3
আসুন আমরা এই লেখাটি পাঁচ বছর পরে সত্যটি দিয়ে শুরু করি । আপনি পার্টিতে কিছুটা দেরী করেছেন। দ্বিতীয়ত, আমি জানি যে অনির্দিষ্টকৃত ধারাবাহিকতাগুলি কার্যকারিতা নয়, তবে আপনি ভাষাটি সোজাসুজি রেখে they গড় প্রোগ্রামারের দৃষ্টিকোণ থেকে, একটি অনির্ধারিত ধারাবাহিকতা ফিরে না আসে তা কেবল এটি একটি শট ফাংশন করে তোলে যা কোনও ফাংশন কী এর সংজ্ঞা অনুসারে সঠিক নয় , তবে এটি অন্তত বোধগম্য
কিথ গোগান

2
আমি পার্টির জন্য দেরি করি না যেহেতু আমি যখন "কর্টিন বনাম জেনারেটর" অনুসন্ধান করি তখন গুগলে এই প্রথম ফলাফল পাই। আমি তাদের পার্থক্য সম্পর্কে কিছু ভাল তথ্য খুঁজে প্রত্যাশা ছিল। যাইহোক আমি এটি অন্য কোথাও খুঁজে পেয়েছি। ধারাবাহিকতা সম্পর্কে আপনার ব্যাখ্যাটি ভুল বলে আমি প্রথম উল্লেখ করি না। সমস্যাটি হ'ল কেউ এটিকে ভুল করে ফেলবে এবং সম্ভবত সে পরে বিভ্রান্ত হবে যখন সে বা সে ভিন্ন কিছুর জন্য একই শব্দ ব্যবহৃত হয়।
ইভানচো

33

কর্টিন এমন একাধিক প্রক্রিয়া যা তাদের কাজটি ঘুরিয়ে নেওয়ার পরে গ্রুপের অন্যান্য কর্টিনগুলিকে নিয়ন্ত্রণ দিতে বিরতি দেয়।

ধারাবাহিকতা হ'ল "কোনও ক্রিয়াকলাপের দিকে নির্দেশক" আপনি কোনও প্রক্রিয়াতে পাস করেন, যখন সেই প্রক্রিয়াটি সম্পাদিত হয় তখন মৃত্যুদণ্ড কার্যকর করতে হবে ("সাথে চালিয়ে যান")।

জেনারেটর (ইন নেট) এমন একটি ভাষা নির্মাণ যা একটি মানকে ছুঁড়ে ফেলতে পারে, পদ্ধতির "বিরতি" কার্যকর করতে পারে এবং পরবর্তী মান জিজ্ঞাসা করার পরে একই বিন্দু থেকে এগিয়ে যেতে পারে।


আমি বুঝতে পারি উত্তরটি সঠিক নাও হতে পারে তবে প্রশ্নের এই স্তরে আমি এটিকে সহজ রাখার চেষ্টা করেছি। তদুপরি, আমি নিজেও এই সমস্ত বুঝতে পারি না :)
zvolkov

পাইথনের একটি জেনারেটর সি # সংস্করণের অনুরূপ, তবে একটি পুনরাবৃত্ত বস্তুর উদাহরণ তৈরি করার জন্য একটি বিশেষ সিনট্যাক্স হিসাবে প্রয়োগ করা হয়, যা আপনার প্রদত্ত "ফাংশন" সংজ্ঞা দ্বারা ফিরিয়ে দেওয়া মানগুলি প্রদান করে।
বেনসন

2
একটি ছোট সংশোধন: "... কল স্ট্যাক এবং সমস্ত ভেরিয়েবল সহ তবে তাদের মূল্যগুলি নয়" (বা কেবল "সমস্ত ভেরিয়েবল" বাদ দিন)। ধারাবাহিকতা মানগুলি সংরক্ষণ করে না, সেগুলিতে কেবল কল স্ট্যাক রয়েছে।
নালীর সাথে

না, ধারাবাহিকতাগুলি "কোনও ফাংশনের প্রতি নির্দেশক" নয়। সর্বাধিক নিখুঁত বাস্তবায়নে, এটি কাজ করার জন্য একটি পয়েন্টার ধারণ করে এবং একটি পরিবেশ স্থানীয় ভেরিয়েবলগুলি ধারণ করে। এবং আপনি কখনই কল / সিসির মতো কিছু ব্যবহার না করে এটি কখনই ফিরে আসে না return
নালাগিনরুত

9

পাইথনের নতুন সংস্করণে আপনি জেনারেটরের সাথে মানগুলি পাঠাতে পারেন generator.send(), যা পাইথন জেনারেটরকে কার্যকরভাবে কর্টিন তৈরি করে।

পাইথন জেনারেটর এবং গ্রিনলেট বলে অন্য জেনারেটরের মধ্যে প্রধান পার্থক্যটি হ'ল পাইথনটিতে আপনার yield valueকেবলমাত্র কলারে ফিরে আসতে পারেন। গ্রিনলেটে থাকাকালীন target.switch(value)আপনাকে একটি নির্দিষ্ট টার্গেটের কর্টিনে নিয়ে targetযেতে পারে এবং এমন কোনও মান দিতে পারে যেখানে চালানো চালিয়ে যাওয়া থাকবে।


3
তবে পাইথনে, সমস্ত yieldকল একই ফাংশনে থাকতে হবে, যাকে "জেনারেটর" বলা হয়। আপনি yieldকোনও উপ-ফাংশন থেকে পারবেন না , এজন্য পাইথনকে আধা-করোটাইনস বলা হয় , যখন লুয়াকে অসম্পূর্ণ কর্টিন রয়েছে । (ফলন প্রচারের প্রস্তাব রয়েছে, তবে আমি মনে করি সেগুলি কেবল
জলাবদ্ধ হয়ে পড়েছে

7
@ সিডুএন ২০০১:: উইনস্টনের মন্তব্য) পাইথন ৩.৩ "" থেকে ফলন "প্রকাশ করে যা আপনাকে সাব-জেনারেটর থেকে ফল দেয় yield
লিনাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.