background threads

V

Venkat Akkineni

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"
 
M

Michael Baker

[Note: parts of this message were removed to make it a legal post.]

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 <
 
V

Venkat Akkineni

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
 
R

Robert Klemme

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
 
V

Venkat Akkineni

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
 
R

Robert Klemme

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|
=A0# =A0printf "%-20s %5d\n", "Foreground", i
=A0# 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

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top