This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Actor not creating enough threads

7 replies
Baldur Norddahl
Joined: 2009-02-01,
User offline. Last seen 42 years 45 weeks ago.
Hi,
I am trying to create 10 parallel threads to do some work. But for some reason I only get 3 threads. What am I doing wrong? Is there a way to control how many threads the Actor library will use?
The following program will give output like this:
Creating actor #1Creating actor #2Creating actor #3Creating actor #4Creating actor #5 Creating actor #6Creating actor #7Creating actor #8Creating actor #9Creating actor #10Scanning(3) vlan3: 79.98.195.4Scanning(1) vlan3: 79.98.195.2 Scanning(2) vlan3: 79.98.195.3vlan3 79.98.195.2 has MAC [00:23:8B:EA:5B:D2]Scanning(1) vlan3: 79.98.195.12Scanning(3) vlan3: 79.98.195.13Scanning(2) vlan3: 79.98.195.14 vlan3 79.98.195.13 has MAC [00:18:39:BF:C3:E5]Scanning(3) vlan3: 79.98.195.15Scanning(1) vlan3: 79.98.195.16Scanning(2) vlan3: 79.98.195.17Scanning(3) vlan3: 79.98.195.18 vlan3 79.98.195.18 has MAC [00:21:9B:08:B7:9E]Scanning(3) vlan3: 79.98.195.19Scanning(1) vlan3: 79.98.195.20...
As you can see, it is doing all the work in actor 1 to 3 and ignoring the rest. The very last thing it does before exiting is running actor 4 to 10 once.
Here is the program listing:
import scala.actors.Actorimport scala.actors.Actor._
object Apall {  val ranges = List(           ("vlan3","79.98.195.",2,58),          ("vlan11","79.98.193.",2,126),          ("vlan12","79.98.193.",130,254),          ("vlan13","79.98.194.",2,126),           ("vlan14","79.98.194.",130,254),          ("vlan15","79.98.197.",1,126)  )
  case class ScanMessage(vlan: String,ip: String)   case class GetOneIP(who: Actor)
  var count=10;  val ipsToScan = actor {    var ips = for((vlan,ipRange,firstOctet,lastOctet) <- ranges; octet <- firstOctet to lastOctet) yield ScanMessage(vlan,ipRange+octet)     while(true) {      receive {        case GetOneIP(who) =>          if (ips.isEmpty) {            count -= 1            if (count==0) System.exit(0)           } else {            who ! ips.head            ips = ips.tail          }      }    }  }
  val count2 = count  for(i <- 1 to count2) {     println("Creating actor #"+i)    val thisActor = new Actor {    val me = i;    def act() = {      while(true) {        receive {          case ScanMessage(vlan,ip) =>             println("Scanning("+me+") "+vlan+": "+ip)            val output = Sh("arping -w 1 -D -I "+vlan+" "+ip+" |").foldLeft(""){ (a,b) => a+"\n"+b }             for(mac <- "\\[([0-9A-F]{1,2}:){5}[0-9A-F]{1,2}\\]".r.findFirstIn(output)) {              println(vlan+" "+ip+" has MAC "+mac)            }             ipsToScan ! GetOneIP(this)        }      }    }}    thisActor.start    ipsToScan ! GetOneIP(thisActor)  }
  def main(args: Array[String]) {   }}
Thanks,
Baldur
Baldur Norddahl
Joined: 2009-02-01,
User offline. Last seen 42 years 45 weeks ago.
Re: Actor not creating enough threads
I figured the answer to this myself. I had to do System.setProperty("actors.corePoolSize","20").
However the documentation claims the framework will start as many threads as needed. Instead it starves my actors forever. Worse, it starts twice the number of cores threads. Which means it might be working just fine on a my development machine that could be a nice quad core, and fail horrible on the target machine that could be a single core.
Baldur

2010/2/26 Baldur Norddahl <baldur.norddahl@gmail.com>
Hi,
I am trying to create 10 parallel threads to do some work. But for some reason I only get 3 threads. What am I doing wrong? Is there a way to control how many threads the Actor library will use?
The following program will give output like this:
Creating actor #1Creating actor #2Creating actor #3Creating actor #4Creating actor #5 Creating actor #6Creating actor #7Creating actor #8Creating actor #9Creating actor #10Scanning(3) vlan3: 79.98.195.4Scanning(1) vlan3: 79.98.195.2 Scanning(2) vlan3: 79.98.195.3vlan3 79.98.195.2 has MAC [00:23:8B:EA:5B:D2]Scanning(1) vlan3: 79.98.195.12Scanning(3) vlan3: 79.98.195.13Scanning(2) vlan3: 79.98.195.14 vlan3 79.98.195.13 has MAC [00:18:39:BF:C3:E5]Scanning(3) vlan3: 79.98.195.15Scanning(1) vlan3: 79.98.195.16Scanning(2) vlan3: 79.98.195.17Scanning(3) vlan3: 79.98.195.18 vlan3 79.98.195.18 has MAC [00:21:9B:08:B7:9E]Scanning(3) vlan3: 79.98.195.19Scanning(1) vlan3: 79.98.195.20...
As you can see, it is doing all the work in actor 1 to 3 and ignoring the rest. The very last thing it does before exiting is running actor 4 to 10 once.
Here is the program listing:
import scala.actors.Actorimport scala.actors.Actor._
object Apall {  val ranges = List(           ("vlan3","79.98.195.",2,58),          ("vlan11","79.98.193.",2,126),          ("vlan12","79.98.193.",130,254),          ("vlan13","79.98.194.",2,126),           ("vlan14","79.98.194.",130,254),          ("vlan15","79.98.197.",1,126)  )
  case class ScanMessage(vlan: String,ip: String)   case class GetOneIP(who: Actor)
  var count=10;  val ipsToScan = actor {    var ips = for((vlan,ipRange,firstOctet,lastOctet) <- ranges; octet <- firstOctet to lastOctet) yield ScanMessage(vlan,ipRange+octet)     while(true) {      receive {        case GetOneIP(who) =>          if (ips.isEmpty) {            count -= 1            if (count==0) System.exit(0)           } else {            who ! ips.head            ips = ips.tail          }      }    }  }
  val count2 = count  for(i <- 1 to count2) {     println("Creating actor #"+i)    val thisActor = new Actor {    val me = i;    def act() = {      while(true) {        receive {          case ScanMessage(vlan,ip) =>             println("Scanning("+me+") "+vlan+": "+ip)            val output = Sh("arping -w 1 -D -I "+vlan+" "+ip+" |").foldLeft(""){ (a,b) => a+"\n"+b }             for(mac <- "\\[([0-9A-F]{1,2}:){5}[0-9A-F]{1,2}\\]".r.findFirstIn(output)) {              println(vlan+" "+ip+" has MAC "+mac)            }             ipsToScan ! GetOneIP(this)        }      }    }}    thisActor.start    ipsToScan ! GetOneIP(thisActor)  }
  def main(args: Array[String]) {   }}
Thanks,
Baldur

Niko Matsakis
Joined: 2010-02-27,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Actor not creating enough threads
This could be because the Actors library is non-preemptive.  Perhaps you are performing blocking operations in your actors, or looping indefinitely without returning control to the runtime?  

regards,Niko
On Feb 27, 2010, at 1:49 PM, Baldur Norddahl wrote:
I figured the answer to this myself. I had to do System.setProperty("actors.corePoolSize","20").
However the documentation claims the framework will start as many threads as needed. Instead it starves my actors forever. Worse, it starts twice the number of cores threads. Which means it might be working just fine on a my development machine that could be a nice quad core, and fail horrible on the target machine that could be a single core.
Baldur

2010/2/26 Baldur Norddahl <baldur.norddahl@gmail.com>
Hi,
I am trying to create 10 parallel threads to do some work. But for some reason I only get 3 threads. What am I doing wrong? Is there a way to control how many threads the Actor library will use?
The following program will give output like this:
Creating actor #1Creating actor #2Creating actor #3Creating actor #4Creating actor #5 Creating actor #6Creating actor #7Creating actor #8Creating actor #9Creating actor #10Scanning(3) vlan3: 79.98.195.4Scanning(1) vlan3: 79.98.195.2 Scanning(2) vlan3: 79.98.195.3vlan3 79.98.195.2 has MAC [00:23:8B:EA:5B:D2]Scanning(1) vlan3: 79.98.195.12Scanning(3) vlan3: 79.98.195.13Scanning(2) vlan3: 79.98.195.14 vlan3 79.98.195.13 has MAC [00:18:39:BF:C3:E5]Scanning(3) vlan3: 79.98.195.15Scanning(1) vlan3: 79.98.195.16Scanning(2) vlan3: 79.98.195.17Scanning(3) vlan3: 79.98.195.18 vlan3 79.98.195.18 has MAC [00:21:9B:08:B7:9E]Scanning(3) vlan3: 79.98.195.19Scanning(1) vlan3: 79.98.195.20...
As you can see, it is doing all the work in actor 1 to 3 and ignoring the rest. The very last thing it does before exiting is running actor 4 to 10 once.
Here is the program listing:
import scala.actors.Actorimport scala.actors.Actor._
object Apall {  val ranges = List(           ("vlan3","79.98.195.",2,58),          ("vlan11","79.98.193.",2,126),          ("vlan12","79.98.193.",130,254),          ("vlan13","79.98.194.",2,126),           ("vlan14","79.98.194.",130,254),          ("vlan15","79.98.197.",1,126)  )
  case class ScanMessage(vlan: String,ip: String)   case class GetOneIP(who: Actor)
  var count=10;  val ipsToScan = actor {    var ips = for((vlan,ipRange,firstOctet,lastOctet) <- ranges; octet <- firstOctet to lastOctet) yield ScanMessage(vlan,ipRange+octet)     while(true) {      receive {        case GetOneIP(who) =>          if (ips.isEmpty) {            count -= 1            if (count==0) System.exit(0)           } else {            who ! ips.head            ips = ips.tail          }      }    }  }
  val count2 = count  for(i <- 1 to count2) {     println("Creating actor #"+i)    val thisActor = new Actor {    val me = i;    def act() = {      while(true) {        receive {          case ScanMessage(vlan,ip) =>             println("Scanning("+me+") "+vlan+": "+ip)            val output = Sh("arping -w 1 -D -I "+vlan+" "+ip+" |").foldLeft(""){ (a,b) => a+"\n"+b }             for(mac <- "\\[([0-9A-F]{1,2}:){5}[0-9A-F]{1,2}\\]".r.findFirstIn(output)) {              println(vlan+" "+ip+" has MAC "+mac)            }             ipsToScan ! GetOneIP(this)        }      }    }}    thisActor.start    ipsToScan ! GetOneIP(thisActor)  }
  def main(args: Array[String]) {   }}
Thanks,
Baldur


Niko Matsakis
Joined: 2010-02-27,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Actor not creating enough threads

> This could be because the Actors library is non-preemptive. Perhaps you are performing blocking operations in your actors, or looping indefinitely without returning control to the runtime?

To reply to myself, I see that you enclosed a sample program which is not using blocking operations. Sorry, I missed that the first time reading your message. Nonetheless, I suspect the issue you are discussing is related. Basically, I would guess the actors scheduler is not fair, and so each of the first three "consumer" actors greedily continue running so long as they have more messages. The other consumers are starved until the total pool of produced items is exhausted, in which case they finally run. This situation shouldn't cause a deadlock, but could result in some items waiting indefinitely to be processed if the pool of produced items is inexhaustible.

Anyway, I haven't looked at the implementation of the actors runtime in detail, so this is all speculation.

regards,
Niko

Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: Actor not creating enough threads
Try using "react" instead of "receive".   Receive blocks the current thread.


- Josh

On Fri, Feb 26, 2010 at 8:58 AM, Baldur Norddahl <baldur.norddahl@gmail.com> wrote:
Hi,
I am trying to create 10 parallel threads to do some work. But for some reason I only get 3 threads. What am I doing wrong? Is there a way to control how many threads the Actor library will use?
The following program will give output like this:
Creating actor #1Creating actor #2Creating actor #3Creating actor #4Creating actor #5 Creating actor #6Creating actor #7Creating actor #8Creating actor #9Creating actor #10Scanning(3) vlan3: 79.98.195.4Scanning(1) vlan3: 79.98.195.2 Scanning(2) vlan3: 79.98.195.3vlan3 79.98.195.2 has MAC [00:23:8B:EA:5B:D2]Scanning(1) vlan3: 79.98.195.12Scanning(3) vlan3: 79.98.195.13Scanning(2) vlan3: 79.98.195.14 vlan3 79.98.195.13 has MAC [00:18:39:BF:C3:E5]Scanning(3) vlan3: 79.98.195.15Scanning(1) vlan3: 79.98.195.16Scanning(2) vlan3: 79.98.195.17Scanning(3) vlan3: 79.98.195.18 vlan3 79.98.195.18 has MAC [00:21:9B:08:B7:9E]Scanning(3) vlan3: 79.98.195.19Scanning(1) vlan3: 79.98.195.20...
As you can see, it is doing all the work in actor 1 to 3 and ignoring the rest. The very last thing it does before exiting is running actor 4 to 10 once.
Here is the program listing:
import scala.actors.Actorimport scala.actors.Actor._
object Apall {  val ranges = List(           ("vlan3","79.98.195.",2,58),          ("vlan11","79.98.193.",2,126),          ("vlan12","79.98.193.",130,254),          ("vlan13","79.98.194.",2,126),           ("vlan14","79.98.194.",130,254),          ("vlan15","79.98.197.",1,126)  )
  case class ScanMessage(vlan: String,ip: String)   case class GetOneIP(who: Actor)
  var count=10;  val ipsToScan = actor {    var ips = for((vlan,ipRange,firstOctet,lastOctet) <- ranges; octet <- firstOctet to lastOctet) yield ScanMessage(vlan,ipRange+octet)     while(true) {      receive {        case GetOneIP(who) =>          if (ips.isEmpty) {            count -= 1            if (count==0) System.exit(0)           } else {            who ! ips.head            ips = ips.tail          }      }    }  }
  val count2 = count  for(i <- 1 to count2) {     println("Creating actor #"+i)    val thisActor = new Actor {    val me = i;    def act() = {      while(true) {        receive {          case ScanMessage(vlan,ip) =>             println("Scanning("+me+") "+vlan+": "+ip)            val output = Sh("arping -w 1 -D -I "+vlan+" "+ip+" |").foldLeft(""){ (a,b) => a+"\n"+b }             for(mac <- "\\[([0-9A-F]{1,2}:){5}[0-9A-F]{1,2}\\]".r.findFirstIn(output)) {              println(vlan+" "+ip+" has MAC "+mac)            }             ipsToScan ! GetOneIP(this)        }      }    }}    thisActor.start    ipsToScan ! GetOneIP(thisActor)  }
  def main(args: Array[String]) {   }}
Thanks,
Baldur

Erik Engbrecht
Joined: 2008-12-19,
User offline. Last seen 3 years 18 weeks ago.
Re: Actor not creating enough threads
Still, the scheduler is supposed to detect when all its threads are blocked and spawn more up to the limit.

On Sat, Feb 27, 2010 at 10:40 AM, Josh Suereth <joshua.suereth@gmail.com> wrote:
Try using "react" instead of "receive".   Receive blocks the current thread.


- Josh

On Fri, Feb 26, 2010 at 8:58 AM, Baldur Norddahl <baldur.norddahl@gmail.com> wrote:
Hi,
I am trying to create 10 parallel threads to do some work. But for some reason I only get 3 threads. What am I doing wrong? Is there a way to control how many threads the Actor library will use?
The following program will give output like this:
Creating actor #1Creating actor #2Creating actor #3Creating actor #4Creating actor #5 Creating actor #6Creating actor #7Creating actor #8Creating actor #9Creating actor #10Scanning(3) vlan3: 79.98.195.4Scanning(1) vlan3: 79.98.195.2 Scanning(2) vlan3: 79.98.195.3vlan3 79.98.195.2 has MAC [00:23:8B:EA:5B:D2]Scanning(1) vlan3: 79.98.195.12Scanning(3) vlan3: 79.98.195.13Scanning(2) vlan3: 79.98.195.14 vlan3 79.98.195.13 has MAC [00:18:39:BF:C3:E5]Scanning(3) vlan3: 79.98.195.15Scanning(1) vlan3: 79.98.195.16Scanning(2) vlan3: 79.98.195.17Scanning(3) vlan3: 79.98.195.18 vlan3 79.98.195.18 has MAC [00:21:9B:08:B7:9E]Scanning(3) vlan3: 79.98.195.19Scanning(1) vlan3: 79.98.195.20...
As you can see, it is doing all the work in actor 1 to 3 and ignoring the rest. The very last thing it does before exiting is running actor 4 to 10 once.
Here is the program listing:
import scala.actors.Actorimport scala.actors.Actor._
object Apall {  val ranges = List(           ("vlan3","79.98.195.",2,58),          ("vlan11","79.98.193.",2,126),          ("vlan12","79.98.193.",130,254),          ("vlan13","79.98.194.",2,126),           ("vlan14","79.98.194.",130,254),          ("vlan15","79.98.197.",1,126)  )
  case class ScanMessage(vlan: String,ip: String)   case class GetOneIP(who: Actor)
  var count=10;  val ipsToScan = actor {    var ips = for((vlan,ipRange,firstOctet,lastOctet) <- ranges; octet <- firstOctet to lastOctet) yield ScanMessage(vlan,ipRange+octet)     while(true) {      receive {        case GetOneIP(who) =>          if (ips.isEmpty) {            count -= 1            if (count==0) System.exit(0)           } else {            who ! ips.head            ips = ips.tail          }      }    }  }
  val count2 = count  for(i <- 1 to count2) {     println("Creating actor #"+i)    val thisActor = new Actor {    val me = i;    def act() = {      while(true) {        receive {          case ScanMessage(vlan,ip) =>             println("Scanning("+me+") "+vlan+": "+ip)            val output = Sh("arping -w 1 -D -I "+vlan+" "+ip+" |").foldLeft(""){ (a,b) => a+"\n"+b }             for(mac <- "\\[([0-9A-F]{1,2}:){5}[0-9A-F]{1,2}\\]".r.findFirstIn(output)) {              println(vlan+" "+ip+" has MAC "+mac)            }             ipsToScan ! GetOneIP(this)        }      }    }}    thisActor.start    ipsToScan ! GetOneIP(thisActor)  }
  def main(args: Array[String]) {   }}
Thanks,
Baldur




--
http://erikengbrecht.blogspot.com/
Erik Engbrecht
Joined: 2008-12-19,
User offline. Last seen 3 years 18 weeks ago.
Re: Re: Actor not creating enough threads
Which version of Scala are you using and on which JVM?

On Sat, Feb 27, 2010 at 7:49 AM, Baldur Norddahl <baldur.norddahl@gmail.com> wrote:
I figured the answer to this myself. I had to do System.setProperty("actors.corePoolSize","20").
However the documentation claims the framework will start as many threads as needed. Instead it starves my actors forever. Worse, it starts twice the number of cores threads. Which means it might be working just fine on a my development machine that could be a nice quad core, and fail horrible on the target machine that could be a single core.
Baldur

2010/2/26 Baldur Norddahl <baldur.norddahl@gmail.com>
Hi,
I am trying to create 10 parallel threads to do some work. But for some reason I only get 3 threads. What am I doing wrong? Is there a way to control how many threads the Actor library will use?
The following program will give output like this:
Creating actor #1Creating actor #2Creating actor #3Creating actor #4Creating actor #5 Creating actor #6Creating actor #7Creating actor #8Creating actor #9Creating actor #10Scanning(3) vlan3: 79.98.195.4Scanning(1) vlan3: 79.98.195.2 Scanning(2) vlan3: 79.98.195.3vlan3 79.98.195.2 has MAC [00:23:8B:EA:5B:D2]Scanning(1) vlan3: 79.98.195.12Scanning(3) vlan3: 79.98.195.13Scanning(2) vlan3: 79.98.195.14 vlan3 79.98.195.13 has MAC [00:18:39:BF:C3:E5]Scanning(3) vlan3: 79.98.195.15Scanning(1) vlan3: 79.98.195.16Scanning(2) vlan3: 79.98.195.17Scanning(3) vlan3: 79.98.195.18 vlan3 79.98.195.18 has MAC [00:21:9B:08:B7:9E]Scanning(3) vlan3: 79.98.195.19Scanning(1) vlan3: 79.98.195.20...
As you can see, it is doing all the work in actor 1 to 3 and ignoring the rest. The very last thing it does before exiting is running actor 4 to 10 once.
Here is the program listing:
import scala.actors.Actorimport scala.actors.Actor._
object Apall {  val ranges = List(           ("vlan3","79.98.195.",2,58),          ("vlan11","79.98.193.",2,126),          ("vlan12","79.98.193.",130,254),          ("vlan13","79.98.194.",2,126),           ("vlan14","79.98.194.",130,254),          ("vlan15","79.98.197.",1,126)  )
  case class ScanMessage(vlan: String,ip: String)   case class GetOneIP(who: Actor)
  var count=10;  val ipsToScan = actor {    var ips = for((vlan,ipRange,firstOctet,lastOctet) <- ranges; octet <- firstOctet to lastOctet) yield ScanMessage(vlan,ipRange+octet)     while(true) {      receive {        case GetOneIP(who) =>          if (ips.isEmpty) {            count -= 1            if (count==0) System.exit(0)           } else {            who ! ips.head            ips = ips.tail          }      }    }  }
  val count2 = count  for(i <- 1 to count2) {     println("Creating actor #"+i)    val thisActor = new Actor {    val me = i;    def act() = {      while(true) {        receive {          case ScanMessage(vlan,ip) =>             println("Scanning("+me+") "+vlan+": "+ip)            val output = Sh("arping -w 1 -D -I "+vlan+" "+ip+" |").foldLeft(""){ (a,b) => a+"\n"+b }             for(mac <- "\\[([0-9A-F]{1,2}:){5}[0-9A-F]{1,2}\\]".r.findFirstIn(output)) {              println(vlan+" "+ip+" has MAC "+mac)            }             ipsToScan ! GetOneIP(this)        }      }    }}    thisActor.start    ipsToScan ! GetOneIP(thisActor)  }
  def main(args: Array[String]) {   }}
Thanks,
Baldur




--
http://erikengbrecht.blogspot.com/
Baldur Norddahl
Joined: 2009-02-01,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Actor not creating enough threads
fm@fm:~$ scala -versionScala code runner version 2.7.5final -- (c) 2002-2008 LAMP/EPFLfm@fm:~$ java -versionjava version "1.6.0_15"Java(TM) SE Runtime Environment (build 1.6.0_15-b03) Java HotSpot(TM) 64-Bit Server VM (build 14.1-b02, mixed mode)

2010/3/1 Erik Engbrecht <erik.engbrecht@gmail.com>
Which version of Scala are you using and on which JVM?

On Sat, Feb 27, 2010 at 7:49 AM, Baldur Norddahl <baldur.norddahl@gmail.com> wrote:
I figured the answer to this myself. I had to do System.setProperty("actors.corePoolSize","20").
However the documentation claims the framework will start as many threads as needed. Instead it starves my actors forever. Worse, it starts twice the number of cores threads. Which means it might be working just fine on a my development machine that could be a nice quad core, and fail horrible on the target machine that could be a single core.
Baldur

2010/2/26 Baldur Norddahl <baldur.norddahl@gmail.com>
Hi,
I am trying to create 10 parallel threads to do some work. But for some reason I only get 3 threads. What am I doing wrong? Is there a way to control how many threads the Actor library will use?
The following program will give output like this:
Creating actor #1Creating actor #2Creating actor #3Creating actor #4Creating actor #5 Creating actor #6Creating actor #7Creating actor #8Creating actor #9Creating actor #10Scanning(3) vlan3: 79.98.195.4Scanning(1) vlan3: 79.98.195.2 Scanning(2) vlan3: 79.98.195.3vlan3 79.98.195.2 has MAC [00:23:8B:EA:5B:D2]Scanning(1) vlan3: 79.98.195.12Scanning(3) vlan3: 79.98.195.13Scanning(2) vlan3: 79.98.195.14 vlan3 79.98.195.13 has MAC [00:18:39:BF:C3:E5]Scanning(3) vlan3: 79.98.195.15Scanning(1) vlan3: 79.98.195.16Scanning(2) vlan3: 79.98.195.17Scanning(3) vlan3: 79.98.195.18 vlan3 79.98.195.18 has MAC [00:21:9B:08:B7:9E]Scanning(3) vlan3: 79.98.195.19Scanning(1) vlan3: 79.98.195.20...
As you can see, it is doing all the work in actor 1 to 3 and ignoring the rest. The very last thing it does before exiting is running actor 4 to 10 once.
Here is the program listing:
import scala.actors.Actorimport scala.actors.Actor._
object Apall {  val ranges = List(           ("vlan3","79.98.195.",2,58),          ("vlan11","79.98.193.",2,126),          ("vlan12","79.98.193.",130,254),          ("vlan13","79.98.194.",2,126),           ("vlan14","79.98.194.",130,254),          ("vlan15","79.98.197.",1,126)  )
  case class ScanMessage(vlan: String,ip: String)   case class GetOneIP(who: Actor)
  var count=10;  val ipsToScan = actor {    var ips = for((vlan,ipRange,firstOctet,lastOctet) <- ranges; octet <- firstOctet to lastOctet) yield ScanMessage(vlan,ipRange+octet)     while(true) {      receive {        case GetOneIP(who) =>          if (ips.isEmpty) {            count -= 1            if (count==0) System.exit(0)           } else {            who ! ips.head            ips = ips.tail          }      }    }  }
  val count2 = count  for(i <- 1 to count2) {     println("Creating actor #"+i)    val thisActor = new Actor {    val me = i;    def act() = {      while(true) {        receive {          case ScanMessage(vlan,ip) =>             println("Scanning("+me+") "+vlan+": "+ip)            val output = Sh("arping -w 1 -D -I "+vlan+" "+ip+" |").foldLeft(""){ (a,b) => a+"\n"+b }             for(mac <- "\\[([0-9A-F]{1,2}:){5}[0-9A-F]{1,2}\\]".r.findFirstIn(output)) {              println(vlan+" "+ip+" has MAC "+mac)            }             ipsToScan ! GetOneIP(this)        }      }    }}    thisActor.start    ipsToScan ! GetOneIP(thisActor)  }
  def main(args: Array[String]) {   }}
Thanks,
Baldur




--
http://erikengbrecht.blogspot.com/

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland