Background threads

Hello

Here is a class when run starts printing numbers to the console in a new
thread. The c.setSignal(true) starts the infinite loop. The loop keeps
printing to the console. But the program never goes beyond that
statement and understandably so, therefore "I am here" never gets
printed.

I am trying to start a thread and let it run in the background until I
call a method and set the aFlag to false. I am unable to visualize this
using semaphores and threads. Could somebody help me.

class Example

  attr_accessor :aFlag , :tr

  def run
    self.aFlag = false
    i = 0

    self.tr=Thread.new(self.aFlag) { |aFlag|
      while !aFlag
        puts i

        i=i+1
        sleep 1
      end
    }
  end

  def display
    self.run
    sleep
  end

  def setSignal(signal)
    if signal == true
      display
    else
      c.aFlag=true
    end
  end

end

  c = Example.new
  c.setSignal(true)

puts "I am here"

···

--
Posted via http://www.ruby-forum.com/.

I'm not sure that I understand your question, but there are few things I see
that might be problematic. One problem is that you pass the variable that
you want to change, aFlag, to the Thread constructor. This creates a local
copy of aFlag for the thread. When you change aFlag to true inside of
setSignal, it's not changing the copy of aFlag used by your thread. If you
want to access the same aFlag that you set to false at the top of your run
method, you would do it as follows:

self.aFlag = false

Thread.new() { |arg|
while !self.aFlag
  # do something
end
}

If you do this, you'll need to be sure to prevent your two threads from
accessing the aFlag variable at the same time with a mutex lock.

Inside of setSignal you say c.aFlag = true. I'm assuming you mean self.aFlag
= true.

In display you call sleep without a parameter. This will cause your main
thread to sleep forever after you start the second thread, meaning that your
program will stop there.

I hope this helps!

···

On Fri, Dec 17, 2010 at 7:56 PM, Venkat Akkineni < venkatram.akkineni@gmail.com> wrote:

Hello

Here is a class when run starts printing numbers to the console in a new
thread. The c.setSignal(true) starts the infinite loop. The loop keeps
printing to the console. But the program never goes beyond that
statement and understandably so, therefore "I am here" never gets
printed.

I am trying to start a thread and let it run in the background until I
call a method and set the aFlag to false. I am unable to visualize this
using semaphores and threads. Could somebody help me.

class Example

attr_accessor :aFlag , :tr

def run
   self.aFlag = false
   i = 0

   self.tr=Thread.new(self.aFlag) { |aFlag|
     while !aFlag
       puts i

       i=i+1
       sleep 1
     end
   }
end

def display
   self.run
   sleep
end

def setSignal(signal)
   if signal == true
     display
   else
     c.aFlag=true
   end
end

end

c = Example.new
c.setSignal(true)

puts "I am here"

--
Posted via http://www.ruby-forum.com/\.

Mike

        Thanks for your reply. The flag is wrong indeed. I didn't notice
this because the 'else' part of setSignal never gets executed with the
current setup. You will notice that the program runs exactly the same
way even when all commands inside setSignal except call to
display function are commented.

def setSignal(signal)
# if signal == true
      display
# else
# self.aFlag=true
# end
  end

When I change the display function to the following

def display
    self.run
    sleep 20
  end

program prints 'I am here' after 20 seconds.

The reason I did not have an argument for sleep is I wan't the thread
run indefinitely until I call it off some how. This is the desired
effect.

Two approaches I have tried are

1.) loop through indefinitely around necessary code block.
2.) create a thread around the above loop and call Thread.join.

Both the above approaches stop execution where ever these blocks are
called from. Hence I am unable to push the execution of the thread to
the background.

Your thoughts and help ...

Thanks
Venkat

···

--
Posted via http://www.ruby-forum.com/.

Mike

         Thanks for your reply. The flag is wrong indeed. I didn't notice
this because the 'else' part of setSignal never gets executed with the
current setup. You will notice that the program runs exactly the same
way even when all commands inside setSignal except call to
display function are commented.

def setSignal(signal)
# if signal == true
       display
# else
# self.aFlag=true
# end
   end

When I change the display function to the following

  def display
     self.run
     sleep 20
   end

program prints 'I am here' after 20 seconds.

The reason I did not have an argument for sleep is I wan't the thread
run indefinitely until I call it off some how. This is the desired
effect.

Two approaches I have tried are

1.) loop through indefinitely around necessary code block.

I am not sure what you mean.

2.) create a thread around the above loop and call Thread.join.

If you create a thread and then do nothing but joining it you don't need a thread at all.

Both the above approaches stop execution where ever these blocks are
called from. Hence I am unable to push the execution of the thread to
the background.

Your thoughts and help ...

I have no idea how your code looks and what exactly you are describing here. This is what I'd do.

require 'monitor'

class Example
   include MonitorMixin

   def keep_running=(x)
     synchronize do
       @keep_running = x
     end
   end

   def keep_running?
     synchronize do
       @keep_running
     end
   end

   attr_reader :thread

   def display
     self.keep_running = true

     @thread = Thread.new do
       i = 0

       while keep_running?
         printf "%-20s %5d\n", "Background", i
         i += 1

         sleep 1
       end
     end
   end
end

e = Example.new
e.display

10.times do |i|
   printf "%-20s %5d\n", "Foreground", i
   sleep 3
end

e.keep_running = false

e.thread.join

puts "done."

Kind regards

  robert

···

On 18.12.2010 15:10, Venkat Akkineni wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Hello Robert

Thanks for your code and help. By commenting a few lines in your code I
will try to make my argument.

if you comment out the following lines in the code above. You will
notice
that the thread exists only momentarily even with the join. It won't
even print the "Background" the first time.

#10.times do |i|
# printf "%-20s %5d\n", "Foreground", i
  # sleep 3
#end

While I could use a loop like the one above, it will stop all execution
at that point until the hamster has run its length. How can I change the
code so that the main thread respects the currently running thread and
let it do its thing before it exists. Notice that I have read the
documentation and understand that when main thread exits it will kill
all the running threads.

Also my code attached to the email. It is a simple window class
that uses SDL. SDL window stays alive as long as there is a loop right
next to window initialization.

-> When add the loop in a method and call it from some where else . The
execution stops at the line I am calling it.
-> So I thought creating a new thread will help, but when I create a
thread window appears for an instant and disappears.
-> I try adding thread.join right after creating an instance of a class
that encloses window creation. This causes freezing of the execution at
thread.join

I am pretty sure that I am going about this the wrong way but not sure
what is the right way.

Thanks
Venkat

Attachments:
http://www.ruby-forum.com/attachment/5607/window.rb

···

--
Posted via http://www.ruby-forum.com/.

Hello Robert

Thanks for your code and help. By commenting a few lines in your code I
will try to make my argument.

if you comment out the following lines in the code above. You will
notice
that the thread exists only momentarily even with the join. It won't
even print the "Background" the first time.

#10.times do |i|
# printf "%-20s %5d\n", "Foreground", i
# sleep 3
#end

Well, obviously because - as you state below - when the main thread
dies the interpreter exits and takes all other threads with it.

While I could use a loop like the one above, it will stop all execution
at that point until the hamster has run its length. How can I change the
code so that the main thread respects the currently running thread and
let it do its thing before it exists.

You need to join as I showed in my example.

Notice that I have read the
documentation and understand that when main thread exits it will kill
all the running threads.

Also my code attached to the email. It is a simple window class
that uses SDL. SDL window stays alive as long as there is a loop right
next to window initialization.

-> When add the loop in a method and call it from some where else . The
execution stops at the line I am calling it.
-> So I thought creating a new thread will help, but when I create a
thread window appears for an instant and disappears.
-> I try adding thread.join right after creating an instance of a class
that encloses window creation. This causes freezing of the execution at
thread.join

I don't know SDL so I cannot comment on that. Maybe you want to do
the window handling in the main thread.

I am pretty sure that I am going about this the wrong way but not sure
what is the right way.

Your main thread needs to do what it needs to do. If it's done with
that it can join the background thread. As simple as that. But first
you should probably get a clear understanding which things need to be
done and which need to be done concurrently. It may turn out that you
don't need any additional threads. Also, since apparently you want to
use a windowing system you should check its documentation because
these tend to have some requirements of their own.

Cheers

robert

···

On Mon, Dec 20, 2010 at 11:24 PM, Venkat Akkineni <venkatram.akkineni@gmail.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/