Question from Ruby Thread concept

hi
please consider the below program,

@i=0;@j=0
def hi
hello
while(@i<10)
puts ‘hi’
@i+=1
end
end
def hello
Thread.new do
while(@j<10)
puts ‘hello’
@j+=1
end
end
end
hi #function call

Output

hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hi
hi
hi
hi
hi
hi
hi
hi
hi
hi

Now my question is I introduce the thread inside the hello function but
it hasn’t run my file parallelly instead execution goes sequentially.
What to do to run both these functions parallelly ? The output might
be like below

hello
hi
hello
hi

Hi Raja,

Most ruby versions doesn’t support native threads. (If you need them I
think the options are jruby and rubinius).
So you shouldn’t expect this specific behaviour you described.
Threads is all about “time slices”.
What is wrong if the “hello” thread is able to print 10x “hello” in
its “time slice” before the control is yielded to the another thread?

To have a slightly different behaviour, test putting a sleep inside
each thread so that the thread “sleeps” and pass the control to the
other thread.

@i=0;@j=0
def hi
hello
while(@i<10)
puts ‘hi’
@i+=1
sleep 0.1
end
end
def hello
Thread.new do
while(@j<10)
puts ‘hello’
@j+=1
sleep 0.1
end
end
end
hi #function call

Best regards,
Abinoam Jr.

hi Abinoam Jr.,

I know of this way of giving sleep statement within the function, but it
won’t suitable for my code. Thank you.

What is the real-world problem you’re trying to solve with concurrent
threads? It’s up to the O/S or lower-level strata when to allocate time
to each thread, so relying on a perfect intermingled 50/50 allocation is
going to leave you frustrated.
There’s usually a better way to solve a problem, so try presenting the
problem as well as your attempted solution.

hi Marc W.,

yes I know of this, But In that condition also Ruby doesn’t fork the
code. It executes sequentially.

Hi Joel P.

I have some need here, I am automating the screens, In the end of the
screen execution,I need to update some data in the xls sheet where My
program waits a long time, so if I could use multithread concept here,
then i would be able to put this updating process as another
thread,program would not stop executing the next screen.

Depends on yoru code. A lot of implementations such as HTTP/IO, running
external commands is what takes most time, then Ruby threads still
provide huge speedups because while one thread is waiting for data to
arrive another can run.

Marc W.

hi

I am sure whether I understood your second paragraph. My case would not
overlap one another because once a new thread goes for updating the
sheet new thread would take care of execution of screen. But
unfortunately no such facility is available I guess from the
aforementioned comments.

If you’re spawning a thread to output data to an excel sheet and this is
triggered within a display loop, you run the risk of overlapping the
excel-output threads.
That said, as long as you join any previous threads, or skip the output
stage if the previous output thread is still incomplete, you should be
able to do this with threads.

I mean you’d have to be sure that the display loop which triggers the
output thread doesn’t loop so quickly that it spawns a second output
thread before the first is complete. Since you stated that the output
takes a long time, this sounds like a danger.

I mean you need to ensure that this doesn’t happen:

Display loop 1
display stuff
thread output1
end

Display loop 2
display stuff
thread output1 - still running
thread output2 - conflict with 1
end

On Fri, Oct 4, 2013 at 12:19 PM, Raja gopalan [email protected]
wrote:

end
Output
hello

Now my question is I introduce the thread inside the hello function but
it hasn’t run my file parallelly instead execution goes sequentially.

Note that even with native threads this output would be possible. The
OS scheduler decides when to give which thread CPU time. So it is
entirely possible to see this outcome. There is nothing wrong with it

  • apart from your expectation maybe. :slight_smile:

What to do to run this both the function parallelly ? The output might
be like below

hello
hi
hello
hi

Individual threads need to run longer to see this effect:

$ ruby -e ‘2.times.map {|i| Thread.new(i) {|x| 10.times {puts
x}}}.each(&:join)’ | uniq
1
0
$ ruby -e ‘2.times.map {|i| Thread.new(i) {|x| 100.times {puts
x}}}.each(&:join)’ | uniq
1
0
$ time ruby -e ‘2.times.map {|i| Thread.new(i) {|x| 10000.times {puts
x}}}.each(&:join)’ | uniq
1
0
01
1

0
01
1

0

real 0m0.100s
user 0m0.068s
sys 0m0.004s

You see: there’s nothing wrong with the code. Ruby or the OS
scheduler just decided to give individual threads more time before
they are switched. Note also that IO does influence how scheduling is
handled since eventually there can be only one character written from
one thread - a text terminal does not allow for multiple characters at
the same position at the same time.

Kind regards

robert

Hi Joel P.,

what you are saying is correct, But My codition is bit different.

def fun

   ..............
   .............
   .............
   .............

Thread.new{
fun1()
}

end

def fun1()

Updation to xls happens here.

end
def fun2()



end

Now the execution sequence follows

fun
fun2

Now since fun1 has to be executed before fun2, fun2 has to be delayed
until fun1 completes the execution.So If fun1 and fun2 executes parrally
fun2 wouldn’t be delayed.This is what I meant.

hi Robert K.,

I understood what you meant,when a thread takes longer time OS
automatically spawns second thread. But my requirement was as I stated
above comment to Joel P… So If Ruby spawns a new thread according
to my wish,that would be useful for me.Is there any way?

On Sun, Oct 6, 2013 at 11:34 AM, Raja gopalan [email protected]
wrote:

hi Robert K.,

I understood what you meant,when a thread takes longer time OS
automatically spawns second thread.

I did not say that at all! The OS does not just spawn threads if
something takes longer. The user is responsible for spawning threads.
The OS only schedules them according to criteria implemented in its
scheduler.

But my requirement was as I stated
above comment to Joel P… So If Ruby spawns a new thread according
to my wish,that would be useful for me.

To repeat myself: it’s the decision of the scheduler (either OS or
Ruby) when it will execute which thread. Your two threads will be
perfectly executed in parallel as I have demonstrated with my last
posting. Your tests just did not do enough to trigger alternation.
And if they don’t do much then it’s probably also not an issue to have
them executed sequentially.

If you have requirements that certain things need to happen in order
you need to properly synchronize threads anyway. There’s monitors,
condition variables, blocking queues etc.

Cheers

robert

Hi Robert K.,

Oh ok, sorry for misunderstanding, Now I understood. thank you.