• Login
sketchucation logo sketchucation
  • Login
🔌 Quick Selection | Try Didier Bur's reworked classic extension that supercharges selections in SketchUp Download

Ruby 2.0.0 Threads in SU | how to keep a subthread running?

Scheduled Pinned Locked Moved Developers' Forum
20 Posts 6 Posters 1.6k Views 6 Watching
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    SR20VET
    last edited by 14 Aug 2014, 18:38

    Hi SU,

    I'm testing some multithreading in Ruby.
    It seems like the main thread goes into a sleep state when the user is not interacting with Sketchup and/or no script is executing.

    Take a look at this:

    seconds = 0;
    counter_thread = Thread.start do 
    	loop do
    		seconds += 1;
    		sleep(1);
    	end#do
    end#do
    

    If I just leave the ruby console for what it is after entering this script and don't interact with SU for some seconds, this new thread doesn't run. If I type

    seconds
    

    in the console it just says, 1 or 2. However, if I do react with SU, just move the mouse, change the camera position, ... the thread does run and the seconds gets updated.

    Spawning a timer on the main thread also keeps the message pump running, but not at full "speed". After some time the seconds are incorrect.

    I was wondering if there is some way to keep a subthread running, without the need to interact with SU?

    1 Reply Last reply Reply Quote 0
    • A Offline
      Anton_S
      last edited by 14 Aug 2014, 19:07

      I can't reproduce what your experiencing: Entering this into console, closing console, wait a little without motion, open console, write seconds, but I get like 15, or 20 seconds which is about right.

      Can you try this code in console? I know its same code, but it could make it different.

      seconds = 0; Thread.new(){ while true; seconds += 1; sleep(1) end }

      I am using Windows, FYI

      1 Reply Last reply Reply Quote 0
      • S Offline
        SR20VET
        last edited by 14 Aug 2014, 19:21

        That's funny. If I close the console it does count indeed! But, when I press ENTER after entering the script, sit and wait for 15 seconds and then enter seconds, it does return 1 - 2

        It look like the SU window has to have focus or a mouse hover.

        1 Reply Last reply Reply Quote 0
        • A Offline
          Anton_S
          last edited by 14 Aug 2014, 19:25

          Hmm, I tried your technique, but I still get like a descent time.

          Aha! When I enter this in console and unfocus the window the thread stops running, but when I refocus, it starts running again. I think that's how Windows work...

          1 Reply Last reply Reply Quote 0
          • S Offline
            SR20VET
            last edited by 14 Aug 2014, 19:28

            Hmm.

            1 Reply Last reply Reply Quote 0
            • A Offline
              Anton_S
              last edited by 14 Aug 2014, 19:55

              I was wrong about automatic Windows Thread Suspension. All you need to due is call thread.run or thread.wakeup after creating the thread:
              seconds = 0; t = Thread.new(){ while true; seconds += 1; sleep(1) end }; t.run

              It seems to work even if I suspend/deactivate the window. Can you verify?

              1 Reply Last reply Reply Quote 0
              • S Offline
                SR20VET
                last edited by 14 Aug 2014, 21:32

                I have the same issues with your latest code. When I simply enter the code, press ENTER, wait a couble of seconds and then type seconds, still not a proper amount of seconds.

                Although it seems that, while I'm writing this post, the thread is running... while at the start of the thread I entered "seconds" a couple of times, still with about 10 seconds.

                I'll try: seconds = 0; t = Thread.new(){ while true; seconds += 1; sleep(1) end }; t.run
                and puts "seconds: #{seconds} and time: #{Time.now}"; a few times. Here is the result in the console, it does run, but not perfect:

                seconds = 0; t = Thread.new(){ while true; seconds += 1; sleep(1) end }; t.run
                #<Thread:0x92a18d8 run>
                puts "seconds: #{seconds} and time: #{Time.now}";
                seconds: 1 and time: 2014-08-14 23:39:00 +0200
                nil
                puts "seconds: #{seconds} and time: #{Time.now}";
                seconds: 7 and time: 2014-08-14 23:39:07 +0200
                nil
                puts "seconds: #{seconds} and time: #{Time.now}";
                seconds: 14 and time: 2014-08-14 23:39:15 +0200
                nil
                puts "seconds: #{seconds} and time: #{Time.now}";
                seconds: 25 and time: 2014-08-14 23:39:28 +0200
                nil
                puts "seconds: #{seconds} and time: #{Time.now}";
                seconds: 34 and time: 2014-08-14 23:39:39 +0200
                nil
                puts "seconds: #{seconds} and time: #{Time.now}";
                seconds: 43 and time: 2014-08-14 23:39:50 +0200
                nil

                1 Reply Last reply Reply Quote 0
                • T Offline
                  tt_su
                  last edited by 15 Aug 2014, 12:44

                  Yes, we have observed this. We're not sure why as Ruby claims native threads in 2.0 as oppose to the "green" threads in 1.8 - but yet something is amiss. Might be related to the Ruby interpreter running as embedded in SketchUp - which Ruby isn't really designed to. If you run standalone you will probably find it works fine.

                  1 Reply Last reply Reply Quote 0
                  • T Offline
                    tt_su
                    last edited by 15 Aug 2014, 12:47

                    Btw, when sharing variables between threads you probably want to use Mutex. Not that it solves this issue though.

                    1 Reply Last reply Reply Quote 0
                    • S Offline
                      SR20VET
                      last edited by 18 Aug 2014, 09:01

                      Ok tt_su, I might have to go the hard way then, and use native threads in a c++ extension.

                      1 Reply Last reply Reply Quote 0
                      • T Offline
                        tt_su
                        last edited by 18 Aug 2014, 10:07

                        As things stand right now that would be the route to go.

                        We have a GitHub repo with the Ruby libs we use in SketchUp along with Visual Studio and Xcode projects set up: https://github.com/SketchUp/ruby-c-extension-examples

                        1 Reply Last reply Reply Quote 0
                        • S Offline
                          slbaumgartner
                          last edited by 18 Aug 2014, 12:19

                          According to Programming Ruby 1.9 and 2.0 section 12.2, Ruby 1.9 and 2.0 encountered trouble with numerous existing libraries that were not thread-safe. "So, Ruby compromises: it uses native operating system threads but operates only a single thread at a time." That is very likely what you are seeing.

                          1 Reply Last reply Reply Quote 0
                          • T Offline
                            tt_su
                            last edited by 18 Aug 2014, 13:53

                            So much for "multi-threading"... sigh
                            Still, the worker threads appear to act differently under standalone Ruby vs SketchUp embedded Ruby. So we are suffering from some side effect of how Ruby deals with its threads.

                            1 Reply Last reply Reply Quote 0
                            • Dan RathbunD Offline
                              Dan Rathbun
                              last edited by 18 Aug 2014, 19:34

                              What about Ruby 2.1 ?

                              I'm not here much anymore.

                              1 Reply Last reply Reply Quote 0
                              • A Offline
                                Anton_S
                                last edited by 18 Aug 2014, 20:45

                                Here are Ruby 2.1 release notes : https://github.com/ruby/ruby/blob/v2_1_0/NEWS
                                I haven't found anything with threads though.

                                1 Reply Last reply Reply Quote 0
                                • S Offline
                                  SR20VET
                                  last edited by 20 Aug 2014, 17:13

                                  To make sure the subthread is running, we have to put the main thread in a sleep state.
                                  This is because Ruby does switch to another thread (if existing) when a thread goes into a sleep state.

                                  Now, is there a way to automatically put the main thread in a sleep state when the user is not interacting with SU? Once the user starts to interact (mouse movement, click, ...) the sleep state should be interrupted.

                                  I'm not aware of such an event in SU.

                                  For now this:

                                  message_pump = UI.start_timer(0.1, true) do
                                  	sleep(0.1)
                                  end
                                  

                                  does help a bit, but ofcourse, this drastically affects SU performance. Even sleeping for 0.01 seconds does..

                                  1 Reply Last reply Reply Quote 0
                                  • T Offline
                                    tt_su
                                    last edited by 21 Aug 2014, 13:01

                                    I wouldn't go the route of Ruby threads for now. If you really need it then use native threads in C extension.

                                    One scenario where it might be used is where you do multiple calculations in parallel and don't mind locking the main thread. You can then start your worker threads and join them with the main one. But other than that I would not rely on Ruby threads due to the current state of them.

                                    1 Reply Last reply Reply Quote 0
                                    • S Offline
                                      SR20VET
                                      last edited by 25 Aug 2014, 13:00

                                      Yep, I've taken the native threads path. Got the thread running, got even an http server running in that thread. But now, GIL is killing me. Can't call ruby from that second native thread...

                                      1 Reply Last reply Reply Quote 0
                                      • T Offline
                                        tt_su
                                        last edited by 25 Aug 2014, 17:17

                                        Yea, that's another limitation. You can do calculations and such in other threads. But Ruby calls must be done some the main thread.

                                        1 Reply Last reply Reply Quote 0
                                        • icehuliI Offline
                                          icehuli
                                          last edited by 6 Sept 2014, 23:51

                                          @sr20vet said:

                                          Yep, I've taken the native threads path. Got the thread running, got even an http server running in that thread. But now, GIL is killing me. Can't call ruby from that second native thread...

                                          May I ask what exactly you are trying to do? I think you can call ruby from that second native thread.
                                          One important point is that the ruby function needs to be involved in the ruby thread, i.e. the SU thread. So in the c-extension there should be two threads, one is the same SU thread, the other is your second native thread. All ruby codes need to run within the SU thread.

                                          1 Reply Last reply Reply Quote 0
                                          • 1 / 1
                                          • First post
                                            Last post
                                          Buy SketchPlus
                                          Buy SUbD
                                          Buy WrapR
                                          Buy eBook
                                          Buy Modelur
                                          Buy Vertex Tools
                                          Buy SketchCuisine
                                          Buy FormFonts

                                          Advertisement