Multiple instances of Ruby interpreter in my C++ code?


(Thorsten Scheuermann) #1

Well, the threading in the app is cooperative, not preemptive. So if there
was a way to spawn each script in a Ruby thread, and switch to a specific
thread through a C or Ruby call I think I could do it.

Then I could basically do this:

while(!done)
{
switch to my ruby thread
for(a while)
run a line of ruby code
yield()
}

···

-----Original Message-----
From: Sean Middleditch [mailto:elanthis@awesomeplay.com]
Sent: Monday, June 10, 2002 10:11 AM
To: ruby-talk@ruby-lang.org
Subject: RE: multiple instances of Ruby interpreter in my C++ code?

Ew, the threading will be a problem. As mad as some people on the list
may get at me for saying so, in the interest of “the best tool for the
job,” Ruby may not be your best bet if your app requires the
multi-threading.

On the other hand, Ruby itself has great threading support - you may
wish to have your app run in a single OS thread, and let the Ruby
scripts be multi-threaded?

Otherwise, of the languages I know, Lua would probably work best for
you.

On Mon, 2002-06-10 at 10:05, Thorsten Scheuermann wrote:

I wanted to use it in a module for an application to run (currently) very
simple scripts. The thing is that the app is multithreaded and several
instances of this module could run concurrently executing different
scripts.
The scripts right now just look like this:

doSomething(x)
doSomethingElse(A_CONSTANT)

They are automatically generated but eventually I will write new ones by
hand and that’s where the flexibility of Ruby would come in handy. the
calls
that are made in the scripts end up calling wrapped C/C++ functions.
If I have something like
script1: x = foo()
script2: x = bar()
I don’t want the scripts to actually share the variable x. They should be
visible only in the scope of the particular script. Maybe there’s a way of
wrapping these scripts inside a Ruby module through a preprocessor so that
they are isolated from each other?

-Thorsten

-----Original Message-----
From: Sean Middleditch [mailto:elanthis@awesomeplay.com]
Sent: Monday, June 10, 2002 9:49 AM
To: ruby-talk@ruby-lang.org
Subject: Re: multiple instances of Ruby interpreter in my C++ code?

Ruby makes use of a lot of global values - there is no way of doing this
in Ruby currently.

What reason do you have for wanting multiple instances? There may be
another way of accomplishing your goal(s).

On Mon, 2002-06-10 at 09:42, Thorsten Scheuermann wrote:

Hi,

I’m new to Ruby and am currently trying to embed Ruby in a C++ program.
It

is pretty straightforward and I’ve already had some success with that.
However, what I really want is to have several independent instances of
the
interpreter running. Lua for example makes this easy by encapsulating
the

interpreter state in a C struct, but I didn’t see that facility in Ruby.
Is
there any way to accomplish this?

-Thorsten Scheuermann


(Sean Middleditch) #2

To be honest, I’ve never really seen the point of cooperative
multi-tasking. Might as well just be a single “task” will callback
methods… ~,^ The whole purpose of the Ruby threading model is to not
be limited to cooperative multi-tasking.

Again, for what you want, given that you seem to require your app be
multi-threading, another language may be better for you. Ruby is much
more a high-level programming language than it is an embeddable
extension language.

Lua, TCL (as mentioned by Dossy), and others (including
Scriptix) are designed for extending an application, and
will be much better suited to your needs than Ruby.

···

On Mon, 2002-06-10 at 10:17, Thorsten Scheuermann wrote:

Well, the threading in the app is cooperative, not preemptive. So if there
was a way to spawn each script in a Ruby thread, and switch to a specific
thread through a C or Ruby call I think I could do it.

Then I could basically do this:

while(!done)
{
switch to my ruby thread
for(a while)
run a line of ruby code
yield()
}

-----Original Message-----
From: Sean Middleditch [mailto:elanthis@awesomeplay.com]
Sent: Monday, June 10, 2002 10:11 AM
To: ruby-talk@ruby-lang.org
Subject: RE: multiple instances of Ruby interpreter in my C++ code?

Ew, the threading will be a problem. As mad as some people on the list
may get at me for saying so, in the interest of “the best tool for the
job,” Ruby may not be your best bet if your app requires the
multi-threading.

On the other hand, Ruby itself has great threading support - you may
wish to have your app run in a single OS thread, and let the Ruby
scripts be multi-threaded?

Otherwise, of the languages I know, Lua would probably work best for
you.

On Mon, 2002-06-10 at 10:05, Thorsten Scheuermann wrote:

I wanted to use it in a module for an application to run (currently) very
simple scripts. The thing is that the app is multithreaded and several
instances of this module could run concurrently executing different
scripts.
The scripts right now just look like this:

doSomething(x)
doSomethingElse(A_CONSTANT)

They are automatically generated but eventually I will write new ones by
hand and that’s where the flexibility of Ruby would come in handy. the
calls
that are made in the scripts end up calling wrapped C/C++ functions.
If I have something like
script1: x = foo()
script2: x = bar()
I don’t want the scripts to actually share the variable x. They should be
visible only in the scope of the particular script. Maybe there’s a way of
wrapping these scripts inside a Ruby module through a preprocessor so that
they are isolated from each other?

-Thorsten

-----Original Message-----
From: Sean Middleditch [mailto:elanthis@awesomeplay.com]
Sent: Monday, June 10, 2002 9:49 AM
To: ruby-talk@ruby-lang.org
Subject: Re: multiple instances of Ruby interpreter in my C++ code?

Ruby makes use of a lot of global values - there is no way of doing this
in Ruby currently.

What reason do you have for wanting multiple instances? There may be
another way of accomplishing your goal(s).

On Mon, 2002-06-10 at 09:42, Thorsten Scheuermann wrote:

Hi,

I’m new to Ruby and am currently trying to embed Ruby in a C++ program.
It

is pretty straightforward and I’ve already had some success with that.
However, what I really want is to have several independent instances of
the
interpreter running. Lua for example makes this easy by encapsulating
the

interpreter state in a C struct, but I didn’t see that facility in Ruby.
Is
there any way to accomplish this?

-Thorsten Scheuermann


(Jean-Hugues ROBERT) #3

Hello,

To be honest, I’ve never really seen the point of cooperative
multi-tasking.

When making the code “thread safe” is not worth the trouble, it
becomes handy to revert to cooperative multi-tasking. Not to
mention that the code is much easier to debug (race condition bugs
are very much the modern equivalent of the old C dangling pointer
of the past, in terms of difficulty to debug them, to me).

BTW: closures make it much less useful to use preemption, you
achieve the same simplicity/readability with them than with
threads, often, IMO.

About embedding Ruby, I would prefer it to be as easy as it is
for other languages, Tcl for example. The more Ruby users, the
better I feel :wink:

Maybe the multiple instances of Ruby interpreter can be workarounded
with load( file, private_flag), where private_flag deals with
namespaces… I don’t know if there is some equivalent for eval()
but I am pretty sure that by enclosing the code inside a “begin”/"end"
the local variables are going to be “local” to each “instance”.

Switching from one ruby “thread” to another is a matter of calling
the underlying multi-tasker “yield()” function I guess

Conclusion: With cooperative multi-tasking, multiple instances of
Ruby interpreter can be “simulated”. There are probably some data
with “global” scope that need some more handling and that I am
overlooking.

Yours,

Jean-Hugues

···

At 23:24 10/06/2002 +0900, you wrote:


(Sean Middleditch) #4

Hello,

To be honest, I’ve never really seen the point of cooperative
multi-tasking.

When making the code “thread safe” is not worth the trouble, it
becomes handy to revert to cooperative multi-tasking. Not to
mention that the code is much easier to debug (race condition bugs
are very much the modern equivalent of the old C dangling pointer
of the past, in terms of difficulty to debug them, to me).

Again, I’d find it simpler to just use a set of callbacks than to go
thru the trouble of implementing a cooperative multi-tasking system. I
guess I’m alone there tho. :stuck_out_tongue:

BTW: closures make it much less useful to use preemption, you
achieve the same simplicity/readability with them than with
threads, often, IMO.

Minus the preemption, which is often the point of threading - performing
multiple tasks simultaneously without having to worry about the other
threads. i.e., large tasks that require lots of processing can either
just be set to run with a preempted model, or have to broken up into
chunks in a cooperative model (or sprinkled with thread yields).

About embedding Ruby, I would prefer it to be as easy as it is
for other languages, Tcl for example. The more Ruby users, the
better I feel :wink:

Yes, but again, Ruby simply is a pita when you are embedding, especially
when you need to deal with real multiple OS threads or multiple
interpreter instances. I recall Matz saying he’d like to get rid of all
the global variables in Rite… search the archives for his exact words.

Another thing about embedding languages that I’ve found a pain with most
of them, is when you need to repeatedly call a particular script - most
languages, Ruby included (so far as I can tell) you need to call
load/eval on the textual implementation over and over (and thus have it
reparsed and compiled), or pull some magic to wrap it up in a proc or
something (versus having a single, clean, safe API call to do it for
you).

Maybe the multiple instances of Ruby interpreter can be workarounded
with load( file, private_flag), where private_flag deals with
namespaces… I don’t know if there is some equivalent for eval()
but I am pretty sure that by enclosing the code inside a “begin”/"end"
the local variables are going to be “local” to each “instance”.

That doesn’t fix the problem that Ruby is not thread safe. The Ruby
threads can be dealt with easily enough, but not the OS threads. A
coopertively multi-tasked application may be able to pull off sharing
Ruby (i.e., it’s guaranteed that the last Ruby invocation in thread A is
completed before thread B makes an invocation), but that would be ugly,
and why in all hell you’d want to cooperatively multi-task an
application anyways (neither thread can run simultaneously, and you’ve
already broken up the tasks, in order to be cooperative…)

Switching from one ruby “thread” to another is a matter of calling
the underlying multi-tasker “yield()” function I guess

Conclusion: With cooperative multi-tasking, multiple instances of
Ruby interpreter can be “simulated”. There are probably some data
with “global” scope that need some more handling and that I am
overlooking.

And in the end, this is all a lot of work for a hack around a problem
that doesn’t exist with other languages, which are designed for
embedding. Ruby simply isn’t made for doing this, you’d have to be
either a masochist or a Ruby fanatic (in the bad sense of the word) to
try this kind of thing instead of just using a better suited tool. It’s
the opposite of trying to write a full-scale GUI app in Bash - it’s
possible, but it’s not the right tool for the job.

···

On Mon, 2002-06-10 at 12:27, Jean-Hugues ROBERT wrote:

At 23:24 10/06/2002 +0900, you wrote:

Yours,

Jean-Hugues


(Chris Ross) #5

: On Mon, 2002-06-10 at 12:27, Jean-Hugues ROBERT wrote:
: > Hello,
[snip]
: And in the end, this is all a lot of work for a hack around a problem
: that doesn't exist with other languages, which are designed for
: embedding. Ruby simply isn't made for doing this, you'd have to be
: either a masochist or a Ruby fanatic (in the bad sense of the word) to
: try this kind of thing instead of just using a better suited tool. It's
: the opposite of trying to write a full-scale GUI app in Bash - it's
: possible, but it's not the right tool for the job.

This is a blatent plug, but you should check out ferite. It has threading
in mind and does pretty much what is wanted in this thread [no pun intended].
It's not as mature as ruby but it's getting there slowly. I am releasing
the latest version in about 5 days time, so then is probably a good time
to look at it :slight_smile: It's also meant to sit in other applications :slight_smile:

Give me a shout if you want more information.

</end blatent plug>

Regards,

Chris

···

On Mon, 10 Jun 2002 17:46:53 Sean Middleditch wrote:
--
+------------------------------------------------------------------+

Chris Ross | chris@darkrock.co.uk | ctr@ferite.org |
             > http://www.darkrock.co.uk | http://www.ferite.org |

+------------------------------------------------------------------+
"Salvador Dali for Coca Cola: "It's surreal thing.""