#2627 How to multithread?

isomorph Wed 16 Aug 2017

I want to solve a problem in four threads. All of them should use the same class as datapool. Because they have to read them only it is not necessary to lock the resources. So i have seen the example of the actor model but in that there is for every actor a new instance of the class createt. So i need the same instance for this threads how can i manage this?

And this instruction doesn't work by me:

a := <myClass>(ActorPool()) |msg| { echo(msg); return msg } It says:

  • No constructor found: myClass(sys::Error, |sys::Obj?->sys::Void|)
  • Unknown method myClass.ActorPool When i add manually "using concurrent" it says:
  • Using concurrent which is not a declared dependency for myProject

What's wrong?

SlimerDude Wed 16 Aug 2017

Hi isomorph,

Using concurrent which is not a declared dependency for myProject

That means you have to add concurrent as a project dependency in your project's build.fan. Essentially, just ensure it contains the following:

depends = [
    "sys          1.0.69 - 1.0",
    "concurrent   1.0.69 - 1.0"
]

For more details, see:

Because they have to read them only it is not necessary to lock the resources

By design, Fantom will only let you compile thread safe code, which means only const classes may be shared between Actors and threads. If you need to cheat, then then you could wrap them in an Unsafe class. (See const and unsafe).

Lemme know if this helps!

Steve.

isomorph Wed 16 Aug 2017

Hi Steve,

thanks it definitiv helps. But there is still an error.

  • a := myType::Field(ActorPool()) |msg| {echo(msg); return msg} The eclipse-ide says me following: "No constructor found: Field(concurrent::ActorPool, |sys::Obj?->sys::Void|)"

What's missing?

SlimerDude Wed 16 Aug 2017

Hi, your code looks very, um, confused!

Here's a plain example that you can cut'n'paste'n'run:

using concurrent

class Isomorph {
    static Void main() {
        // example 1 --> extend Actor Class
        actor1  := MyActor(ActorPool())
        future1 := actor1.send("Hello Isomorph!").get()

        
        // example 2 --> pass in func
        actor2  := Actor(ActorPool()) |msg| {
            echo(msg)
            return null
        }
        future2 := actor2.send("Hello Again!")

        // call get() to ensure the actor msgs are processed before the example ends!
        future1.get()
        future2.get()
    }
}

const class MyActor : Actor {
    new make(ActorPool actorPool) : super(actorPool) { }
    
    override Obj? receive(Obj? msg) {
        echo(msg)
        return null
    }
}

Note that in both examples, msg is printed in a different Actor thread to the main.

isomorph Wed 16 Aug 2017

I have copyed that from the examples here: http://fantom.org/doc/examples/concurrent-actors and forgot to do an empty line after the "-" (should just submit -> preview first ... - sorry for that)

  • a := myType::Field(ActorPool()) |msg| {echo(msg); return msg}

It's correct formatted so (the rest after this should be normal text).

Because i want to run four different methods later it's the better way to do four extra classes, so thanks again you really helped.

Login or Signup to reply.