Threads - running something in background

Discussion in 'Ruby' started by Alex Zunega, Sep 3, 2009.

  1. Alex Zunega

    Alex Zunega Guest

    Hey guys,

    I've been studying Ruby for some weeks now but when it comes to
    threads, I know that I am totally unskilled.

    I am trying to build a class which is able to keep updating itself every
    X seconds after being initialized. In general terms it would work like
    this:

    ----
    class Threading_Test
    attr_accessor :i
    def initialize
    @i = 0
    @j = 0
    neverstop = false

    t1 = Thread.new do
    while neverstop == false do
    sleep 0.1 #here's the the problem.
    @i = @i + 1
    end
    end

    t1.run

    puts "I am ready and I keep updating myself. Or not..."
    end
    end
    ----


    The problem occurs when I try to add this "sleep 0.1" into the thread
    block. The thread only seems to become active when I ask for the @i
    value.

    I know that there might be other ways to implement that, but i think
    that it would fit my code better that setting up a Cron task to do so.

    Thank you all for the help.
    --
    Posted via http://www.ruby-forum.com/.
    Alex Zunega, Sep 3, 2009
    #1
    1. Advertising

  2. Alex Zunega

    7stud -- Guest

    Alex Zunega wrote:
    > Hey guys,
    >
    > I've been studying Ruby for some weeks now but when it comes to
    > threads, I know that I am totally unskilled.
    >
    > I am trying to build a class which is able to keep updating itself every
    > X seconds after being initialized. In general terms it would work like
    > this:
    >
    > ----
    > class Threading_Test
    > attr_accessor :i
    > def initialize
    > @i = 0
    > @j = 0
    > neverstop = false
    >
    > t1 = Thread.new do
    > while neverstop == false do
    > sleep 0.1 #here's the the problem.
    > @i = @i + 1
    > end
    > end
    >
    > t1.run
    >
    > puts "I am ready and I keep updating myself. Or not..."
    > end
    > end
    > ----
    >
    >
    > The problem occurs when I try to add this "sleep 0.1" into the thread
    > block. The thread only seems to become active when I ask for the @i
    > value.
    >


    I'm not sure what you mean. Try this:

    class Updater
    attr_accessor :i

    def initialize
    @i = 0

    Thread.new do
    loop do
    sleep(1)
    @i += 1
    puts "....#{@i}"
    end
    end

    end

    end


    upd = Updater.new

    5.times do
    sleep(2)
    puts upd.i
    end

    Here is my output:
    ....1
    1
    ....2
    ....3
    3
    ....4
    ....5
    5
    ....6
    ....7
    7
    ....8
    ....9
    9

    --
    Posted via http://www.ruby-forum.com/.
    7stud --, Sep 3, 2009
    #2
    1. Advertising

  3. Alex Zunega

    7stud -- Guest

    Alex Zunega wrote:
    > Hey guys,
    >
    > I've been studying Ruby for some weeks now but when it comes to
    > threads, I know that I am totally unskilled.
    >


    Also, you should realize that the @i in the class and the @i in the
    thread are the same variable.
    Therefore, things like this can happen:

    class Updater
    attr_accessor :i

    def initialize
    @i = 0

    Thread.new do
    loop do
    sleep(0.3)
    @i += 1
    puts "....#{@i}"
    end
    end

    end

    end


    upd = Updater.new

    3.times do
    sleep(2)
    puts upd.i

    upd.i = 0 #<-----******
    end

    --output:--
    ....1
    ....2
    ....3
    ....4
    ....5
    ....6
    6
    ....1
    ....2
    ....3
    ....4
    ....5
    ....6
    ....7
    7
    ....1
    ....2
    ....3
    ....4
    ....5
    ....6
    6


    --
    Posted via http://www.ruby-forum.com/.
    7stud --, Sep 3, 2009
    #3
  4. Alex Zunega

    Alex Zunega Guest

    7stud -- wrote:
    > Alex Zunega wrote:
    >> Hey guys,
    >>
    >> I've been studying Ruby for some weeks now but when it comes to
    >> threads, I know that I am totally unskilled.
    >>

    >
    > Also, you should realize that the @i in the class and the @i in the
    > thread are the same variable.
    > Therefore, things like this can happen:
    >
    > class Updater
    > attr_accessor :i
    >
    > def initialize
    > @i = 0
    >
    > Thread.new do
    > loop do
    > sleep(0.3)
    > @i += 1
    > puts "....#{@i}"
    > end
    > end
    >
    > end
    >
    > end
    >
    >
    > upd = Updater.new
    >
    > 3.times do
    > sleep(2)
    > puts upd.i
    >
    > upd.i = 0 #<-----******
    > end
    >
    > --output:--
    > ....1
    > ....2
    > ....3
    > ....4
    > ....5
    > ....6
    > 6
    > ....1
    > ....2
    > ....3
    > ....4
    > ....5
    > ....6
    > ....7
    > 7
    > ....1
    > ....2
    > ....3
    > ....4
    > ....5
    > ....6
    > 6



    Hey 7stud,

    Thanks for the very prompt answer. I couldn't make myself clear and I'll
    try harder this time... :)

    I've just removed two lines from the code you genially sent me. Removing
    these two lines I got the behavior I would like to have. See the code
    and results below:

    >> class Updater
    >> attr_accessor :i
    >>

    ?> def initialize
    >> @i = 0
    >>

    ?> Thread.new do
    ?> loop do
    ?>
    ?> @i += 1
    >>

    ?> end
    >> end
    >>

    ?> end
    >>

    ?> end
    => nil
    >> x.i

    => 213336
    >> x.i

    => 237848
    >>


    I just want something to time these iteration (one per second, for
    example), and everytime that I insert some "sleep" method, the Updater
    would "sum 1" to @i only when I try to access @i attribute.

    What I expect, in other words, is to have an @i very close to the number
    of seconds of the object life, just to prove that it works...


    --
    Posted via http://www.ruby-forum.com/.
    Alex Zunega, Sep 3, 2009
    #4
  5. Alex Zunega

    7stud -- Guest

    Alex Zunega wrote:
    >
    > I just want something to time these iteration (one per second, for
    > example), and everytime that I insert some "sleep" method, the Updater
    > would "sum 1" to @i only when I try to access @i attribute.
    >
    > What I expect, in other words, is to have an @i very close to the number
    > of seconds of the object life, just to prove that it works...


    You aren't making any sense. On the one hand, you say that you want @i
    to tell you the number of seconds the object has been "alive". On the
    other hand, you say you only want to add 1 to @i when you try to access
    @i. Which is it?


    --
    Posted via http://www.ruby-forum.com/.
    7stud --, Sep 3, 2009
    #5
  6. Alex Zunega

    Alex Zunega Guest

    7stud -- wrote:
    > Alex Zunega wrote:
    >>
    >> I just want something to time these iteration (one per second, for
    >> example), and everytime that I insert some "sleep" method, the Updater
    >> would "sum 1" to @i only when I try to access @i attribute.
    >>
    >> What I expect, in other words, is to have an @i very close to the number
    >> of seconds of the object life, just to prove that it works...

    >
    > You aren't making any sense. On the one hand, you say that you want @i
    > to tell you the number of seconds the object has been "alive". On the
    > other hand, you say you only want to add 1 to @i when you try to access
    > @i. Which is it?


    Actually, you're right, I was not clear, but I meant the second one.
    After initialized, 10 seconds later, when retrieving @i value I would
    like to see @i as 10, meaning that for 10 times it updated itself.
    --
    Posted via http://www.ruby-forum.com/.
    Alex Zunega, Sep 3, 2009
    #6
  7. Alex Zunega

    7stud -- Guest

    7stud --, Sep 3, 2009
    #7
  8. 7stud's original Updater class seems to meet the requirements.=A0 Are
    you trying to write a class that will perform some work and then sleep
    1.0 seconds and keep a count of the number of iterations it performed?
    Or are you trying to right a class that will perform some work
    exactly once per second?=A0 In the first case, your work will not
    generally fire once a second because the work itself will take a non
    zero amount of time.=A0 The second case is trickier ... maybe this would
    work:

    class PeriodicWorker
    =A0 def initialize(period =3D 1.0)
    =A0=A0=A0 @period =3D period
    =A0 end

    =A0 def run
    =A0=A0=A0 start =3D Time.now.to_f
    =A0=A0=A0 while true
    =A0=A0=A0=A0=A0 yield
    =A0=A0=A0=A0=A0 sleep_time =3D (start + @period) - Time.now.to_f
    =A0=A0=A0=A0=A0 sleep(sleep_time) rescue nil # Punt if the worker took long=
    er
    than @period seconds to run
    =A0=A0=A0=A0=A0 start +=3D @period
    =A0=A0=A0 end
    =A0 end
    end

    worker =3D PeriodicWorker.new

    worker.run do
    =A0puts "Time: #{Time.now.to_f}"
    =A0sleep 0.22
    =A0puts "Finished my work: #{Time.now.to_f}"
    end


    The only issue with this class is if the work takes longer than the
    period, you are creating a spinloop that will suck up 100% of your
    CPU.

    -Doug Seifert
    Douglas Seifert, Sep 4, 2009
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Browne

    Re: long-running background threads

    David Browne, Jun 7, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    344
    David Browne
    Jun 7, 2004
  2. bruce barker

    Re: long-running background threads

    bruce barker, Jun 7, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    391
    bruce barker
    Jun 7, 2004
  3. Guest
    Replies:
    4
    Views:
    471
    Guest
    Oct 13, 2004
  4. Pedro Pinto

    Java Threads - Get running threads

    Pedro Pinto, Apr 8, 2008, in forum: Java
    Replies:
    2
    Views:
    1,400
    Arne Vajhøj
    Apr 9, 2008
  5. Pekka Järvinen
    Replies:
    2
    Views:
    652
    Richard Tobin
    Apr 29, 2008
Loading...

Share This Page