স্কাল অভিনেতা: গ্রহণ বনাম প্রতিক্রিয়া


110

আমাকে প্রথমে বলি যে আমার কাছে জাভা অভিজ্ঞতা রয়েছে তবে আমি সম্প্রতি কার্যকরী ভাষায় আগ্রহী হয়েছি। সম্প্রতি আমি স্কালার দিকে তাকাতে শুরু করেছি যা দেখতে খুব সুন্দর একটি ভাষা বলে মনে হচ্ছে।

যাইহোক, আমি স্কালায় প্রোগ্রামিংয়ে স্কালার অভিনেতার কাঠামোটি সম্পর্কে পড়ছি , এবং একটি জিনিস আমি বুঝতে পারি না। ৩০.৪ অধ্যায়ে বলা হয়েছে যে reactপরিবর্তে receiveব্যবহার করা থ্রেডগুলি পুনরায় ব্যবহার করা সম্ভব করে তোলে যা কার্য সম্পাদনের পক্ষে ভাল, যেহেতু জেভিএমের মধ্যে থ্রেড ব্যয়বহুল।

এর অর্থ কি, যতক্ষণ না আমি reactতার পরিবর্তে কল receiveকরতে পারি, আমি যতটা অভিনেতাকে পছন্দ করি তা শুরু করতে পারি? স্কালা আবিষ্কার করার আগে, আমি এরলংয়ের সাথে খেলছিলাম, এবং প্রোগ্রামিং এরলংয়ের লেখক ঘাম না ভেঙে 200,000 এরও বেশি প্রক্রিয়া তৈরি করার বিষয়ে গর্বিত করেছেন। আমি জাভা থ্রেড দিয়ে এটি করতে ঘৃণা করব। এরালং (এবং জাভা) এর তুলনায় আমি স্কালায় কোন ধরণের সীমা দেখছি?

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

প্রোগ্রামিং ইন স্ক্যালাল অনুসারে , অভিনেতাদের লেখার জন্য লেখাগুলি লেখার reactচেয়ে বেশি কঠিন receive। এটি প্রশংসনীয় শোনায়, যেহেতু reactফিরে আসে না। যাইহোক, বইটি আপনি কীভাবে reactএকটি লুপ ব্যবহার করে কোনও লুপের ভিতরে রাখতে পারেন তা দেখিয়ে চলেছে Actor.loop। ফলস্বরূপ, আপনি পান

loop {
    react {
        ...
    }
}

যা আমার কাছে দেখতে অনেকটা মিল

while (true) {
    receive {
        ...
    }
}

যা বইতে আগে ব্যবহৃত হয়েছে। তবুও, বইটি বলেছে যে "অনুশীলনে, প্রোগ্রামগুলি কমপক্ষে কয়েক'র প্রয়োজন হবে receive"। তাহলে আমি এখানে কী মিস করছি? কি করতে receiveযে কি react, পারব না প্রত্যাবর্তন ব্যতীত? আর আমি কেন যত্ন করব?

অবশেষে, আমি যা বুঝতে পারি না তার মূলে এসে: বইটি উল্লেখ করে রাখে যে কীভাবে reactথ্রেডটি পুনরায় ব্যবহারের জন্য কল স্ট্যাকটি বাতিল করা সম্ভব করে। ওটা কিভাবে কাজ করে? কেন কল স্ট্যাক বাতিল করা প্রয়োজন? এবং কোনও ফাংশন ব্যতিক্রম ( react) ছুঁড়ে দিয়ে শেষ হয়ে গেলে কল স্ট্যাকটি কেন বাতিল করা যেতে পারে , তবে এটি ( receive) ফেরার মাধ্যমে বন্ধ হয়ে গেলে নয় ?

আমার ধারণা আছে যে স্কালায় প্রোগ্রামিং এখানে কিছু মূল বিষয় নিয়ে চকচকে করছে, যা লজ্জাজনক, কারণ অন্যথায় এটি সত্যই একটি দুর্দান্ত বই।


উত্তর:


78

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

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

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


21

উত্তরটি "হ্যাঁ" - যদি আপনার অভিনেতারা আপনার কোডের কোনও কিছুতে অবরুদ্ধ না হয়ে থাকেন এবং আপনি ব্যবহার করছেন react, তবে আপনি আপনার "সমবর্তী" প্রোগ্রামটি একক থ্রেডের মধ্যে চালাতে পারেন ( actors.maxPoolSizeএটি জানতে সিস্টেমের সম্পত্তিটি সেট করার চেষ্টা করুন )।

কল স্ট্যাক বাতিল করার প্রয়োজনীয়তার আরও স্পষ্ট কারণগুলির loopমধ্যে একটি হ'ল অন্যথায় পদ্ধতিটি একটিতে শেষ হবে StackOverflowError। যেমনটি হয়, ফ্রেমওয়ার্কটি চতুরতার সাথে একটি reactনিক্ষেপ করে একটি শেষ করে SuspendActorException, যা লুপিং কোড দ্বারা ধরা হয় যা পদ্ধতিটির reactমাধ্যমে আবার চালায় andThen

কটাক্ষপাত আছে mkBodyপদ্ধতি Actorএবং তারপর seqভয়ঙ্কর চালাক কাপড় - কিভাবে লুপ নিজেই reschedules দেখতে পদ্ধতি!


20

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

  def a = 10;
  while (! done)  {
     receive {
        case msg =>  println("MESSAGE RECEIVED: " + msg)
     }
     println("after receive and printing a " + a)
  }

থ্রেডটি মেসেজ না পাওয়া পর্যন্ত রিসিভ কলটিতে অপেক্ষা করবে এবং তারপরে চালিয়ে যেতে হবে এবং "পরে 10" বার্তা গ্রহণ এবং মুদ্রণ করবে এবং থ্রেডটি ব্লক হওয়ার আগে স্ট্যাক ফ্রেমে থাকা "10" এর মান সহ মুদ্রণ করবে।

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

  def a = 10;
  while (! done)  {
     react {
        case msg =>  println("MESSAGE RECEIVED: " + msg)
     }
     println("after react and printing a " + a) 
  }

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

জাভা অভিনেতা কাঠামো কিলিম আসলে স্ট্যাকটি সংরক্ষণ করে স্ট্যাক রক্ষণাবেক্ষণ করে যা কোনও বার্তা পাওয়ার প্রতিক্রিয়াতে অনিয়ন্ত্রিত হয়ে যায়।


ধন্যবাদ, এটা খুব তথ্যপূর্ণ ছিল। তবে আপনি কি +aকোড স্নিপেটের পরিবর্তে বোঝাতে চেয়েছিলেন +10?
jqno

দুর্দান্ত উত্তর। আমি তাও পাই না।
সান্তিয়াগোবসুলতো

8

এখানে এটি রাখা:

বিপরীতকরণের নিয়ন্ত্রণ ব্যতীত ইভেন্ট ভিত্তিক প্রোগ্রামিং

এই কাগজপত্রগুলি অভিনেতার স্কেল এপিআই থেকে যুক্ত এবং অভিনেতা বাস্তবায়নের জন্য তাত্ত্বিক কাঠামো সরবরাহ করে। এর মধ্যে রয়েছে কেন প্রতিক্রিয়া কখনই ফিরে আসতে পারে না।


এবং দ্বিতীয় কাগজ। খারাপ স্প্যাম নিয়ন্ত্রণ ... :( [থ্রেডস এবং ইভেন্টগুলি একীভূতকারী অভিনেতা ] [২] [২]: lamp.epfl.ch/~phaller/doc/haller07coord.pdf "থ্রেডস এবং ইভেন্টগুলি একীভূত অভিনেতা"
হেক্স্রেন

0

স্কেল / আক্কা নিয়ে আমি কোনও বড় কাজ করিনি, তবে আমি বুঝতে পেরেছি যে অভিনেতাদের নির্ধারিত হওয়ার পদ্ধতিতে খুব উল্লেখযোগ্য পার্থক্য রয়েছে। আক্কা হ'ল একটি স্মার্ট থ্রেডপুল যা অভিনেতাদের ফাঁসি কার্যকর করার সময় ... প্রতিবারের টুকরোটি কোনও অভিনেতার দ্বারা সম্পন্ন করার জন্য একটি বার্তা কার্যকর করা হবে যা এরলংয়ের মতো নয় যা নির্দেশ অনুসারে হতে পারে ?!

এটি আমাকে ভাবতে পরিচালিত করে যে প্রতিক্রিয়া আরও ভাল বলে এটি সূচিত করার জন্য অন্যান্য অভিনেতাদের বিবেচনা করার জন্য বর্তমান থ্রেডের ইঙ্গিত দেয় যেখানে একই অভিনেতার জন্য অন্যান্য বার্তাগুলি সম্পাদন করতে চালিত হিসাবে "থ্রেড" বর্তমান থ্রেডকে গ্রহণ করতে পারে।

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