يمكن سكالا الفاعلة في عملية رسائل متعددة في وقت واحد ؟

StackOverflow https://stackoverflow.com/questions/1007010

  •  06-07-2019
  •  | 
  •  

سؤال

رد في الآونة الأخيرة مسألة الألغام إلى أن فاعل معالجة الرسائل في وقت واحد.هل هذا صحيح ؟ إنني لا أرى شيئا أن يقول صراحة أن (في البرمجة في سكالا) الذي يحتوي على ما يلي مقتطف (pp.593)

اذا كان react طريقة] يجد الرسالة التي يمكن التعامل معها ، [أن] جدول التعامل مع هذه الرسالة في وقت لاحق التنفيذ و رمي استثناء

(التركيز بلدي).اثنين ذات الصلة (و حصرية بشكل متبادل) الأسئلة:

  1. على افتراض فاعل أن عملية رسائل متعددة simulatenously كيف يمكنني القوة فاعل لمعالجة الرسائل 1 في وقت واحد (إذا كان هذا هو ما أود أن تفعل)?(باستخدام receive?)
  2. على افتراض فاعل العمليات رسائل في وقت واحد ، كيف أنا أفضل تنفيذ فاعل وهو في الواقع يمكن أن معالجة الرسائل بشكل متزامن

تحرير:تفعل قليلا من الاختبار يبدو أن تتحمل أن أكون مخطئا و أن الجهات الفاعلة في الواقع متتابعة.حتى إنه السؤال رقم 2 الذي أريد الإجابة

هل كانت مفيدة؟

المحلول

الجهات الفاعلة في العملية رسالة واحدة في كل مرة.الكلاسيكية نمط عملية رسائل متعددة هو واحد المنسق الممثل أمام مجموعة من المستهلكين الفاعلة.إذا كنت تستخدم تتفاعل ثم المستهلك بركة يمكن أن تكون كبيرة ولكن سوف لا تزال لا تستخدم سوى عدد قليل من JVM المواضيع.هنا مثال أين يمكنني إنشاء مجموعة من 10 المستهلكين واحد منسق الجبهة بالنسبة لهم.

import scala.actors.Actor
import scala.actors.Actor._

case class Request(sender : Actor, payload : String)
case class Ready(sender : Actor)
case class Result(result : String)
case object Stop

def consumer(n : Int) = actor {
  loop {
    react {
      case Ready(sender) => 
        sender ! Ready(self)
      case Request(sender, payload) =>
        println("request to consumer " + n + " with " + payload)
        // some silly computation so the process takes awhile
        val result = ((payload + payload + payload) map {case '0' => 'X'; case '1' => "-"; case c => c}).mkString
        sender ! Result(result)
        println("consumer " + n + " is done processing " + result )
      case Stop => exit
    }
  }
}

// a pool of 10 consumers
val consumers = for (n <- 0 to 10) yield consumer(n)

val coordinator = actor {
  loop {
     react {
        case msg @ Request(sender, payload) =>
           consumers foreach {_ ! Ready(self)}
           react {
              // send the request to the first available consumer
              case Ready(consumer) => consumer ! msg
           }
         case Stop => 
           consumers foreach {_ ! Stop} 
           exit
     }
  }
}

// a little test loop - note that it's not doing anything with the results or telling the coordinator to stop
for (i <- 0 to 1000) coordinator ! Request(self, i.toString)

هذا الرمز اختبارات لمعرفة المستهلك هو متاح و يرسل الطلب إلى أن المستهلك.البدائل هي فقط عشوائيا تعيين إلى المستهلكين أو استخدام جدولة راوند روبن.

اعتمادا على ما تقومون به, قد يكون من الأفضل مع سكالا الآجلة.على سبيل المثال, إذا كنت حقا لا تحتاج الجهات الفاعلة ثم كل ما سبق الآلات يمكن أن تكون مكتوبة كما

import scala.actors.Futures._

def transform(payload : String) = {      
  val result = ((payload + payload + payload) map {case '0' => 'X'; case '1' => "-"; case c => c}).mkString
  println("transformed " + payload + " to " + result )
  result
}

val results = for (i <- 0 to 1000) yield future(transform(i.toString))

نصائح أخرى

أعتقد أن الجواب هو أن Actor لا يمكن التعامل مع رسائل aynchronously.إذا كان لديك Actor التي ينبغي الاستماع إلى رسائل أين هذه الرسائل يمكن التعامل معها بشكل غير متزامن, ثم أنها يمكن أن تكون مكتوبة مثل هذا:

val actor_ = actor {

  loop {
    react {
      case msg =>
        //create a new actor to execute the work. The framework can then 
        //manage the resources effectively
        actor {
          //do work here
        }
      }
    }
  }

إذا كنت تريد أن تفعل أشياء متعددة ثم عليك أن تكون باستخدام العديد من الجهات.السبب كله إلى استخدام الجهات الفاعلة في تقسيم العمل بين عدة عمليات مستقلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top