Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Threading with Python

    PYTHON Development
    0
    15
    2.1k
    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.
    • H
      Helper
      last edited by

      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

      On 12/02/2012 at 10:39, xxxxxxxx wrote:

      I'm trying to figure out how to use threading for scripts. And having a hard time of it.

      Here's my list of what I want to accomplish with threading:
      1. Create a thread to run some code in it that is taxing(looping) on my system
      2. Have the ability to stop the process with the ESC key by the user
      3. Have this all done Asynchronously(Not sure if this is possible with scripts)

      Here's a code example to get things started:

      import c4d  
      from c4d import threading  
        
      class MyThread(threading.C4DThread) :  
          
        #Something to run and tax the system  
        def myThreadedFunction(self) :  
            for i in xrange(0,2000) :  
                mt = c4d.threading.GeIsMainThread() #Test if the main thread is running  
                print mt  
                tId = c4d.threading.GeGetCurrentThreadId()#Get the threads ID  
                print tId  
                c4d.StatusSetText(i)   
            c4d.StatusClear()    
        
      def main() :  
        thread = MyThread()  
        thread.Start(c4d.THREADMODE_ASYNC, c4d.THREADPRIORITY_NORMAL)  
        thread.myThreadedFunction()  
        
      if __name__=='__main__':  
        main()
      

      This example has some problems.
      -It returns "true" meaning that it's running in the main thread...Which is bad. I want another thread to be running instead.
      -And I don't know how to add the ESC key to stop it from running.

      -ScottA

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

        On 12/02/2012 at 11:17, xxxxxxxx wrote:

        It is running in the current thread because you are calling it from the current thread. 😉 (Line 19, last line in main())
        The correct version of your could would be:

        import c4d  
        import time  
          
        class MyThread(c4d.threading.C4DThread) :  
          
          def Main(self) :  
              for i in xrange(0, 5) :  
                  if self.TestBreak() :  
                      print "Canceled thread-execution."  
                      return  
                  c4d.StatusSetText("Running since %d seconds." % i)  
                  time.sleep(1)  
              c4d.StatusClear()  
          
          def TestDBreak(self) :  
              bc = c4d.BaseContainer()  
              c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD, c4d.KEY_ESC, bc)  
              # how to proceed?  
          
        thread = MyThread()  
        thread.Start()
        

        But unfortunately I don't know how to proceed after GetInputState is called. Also, it always returns False in the Thread but does return True in the Main-thread.

        @Official Support: Is this as supposed or is it a bug? The container isn't filled in another thread, only in the main-thread.

        Cheers,
        -Niklas

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

          On 12/02/2012 at 12:22, xxxxxxxx wrote:

          Originally posted by xxxxxxxx

          [...]But unfortunately I don't know how to proceed after GetInputState is called. Also, it always returns False in the Thread but does return True in the Main-thread.@Official Support: Is this as supposed or is it a bug? The container isn't filled in another thread, only in the main-thread.Cheers,-Niklas

          Have a look at the SDK docs ("Important threading information"). There are several things that are only allowed in the main thread - esp. GUI functionality (and therefore keyboard input), as the OS wouldn't support it otherwise.

          Best regards,

          Wilfried Behne

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

            On 12/02/2012 at 12:55, xxxxxxxx wrote:

            Can we terminate something that's running in a thread another way?
            For example:Can we use a timer or something similar to stop running a script that's looping for too long?
             
            I tried editing the example Nux posted to do that.
            But even though I think I stopped the thread properly. It didn't stop processing the script.

            -ScottA

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

              On 12/02/2012 at 13:37, xxxxxxxx wrote:

              Originally posted by xxxxxxxx

              Can we terminate something that's running in a thread another way?For example:Can we use a timer or something similar to stop running a script that's looping for too long? I tried editing the example Nux posted to do that.But even though I think I stopped the thread properly. It didn't stop processing the script.-ScottA

              Please have a look at the C4DThread methods described in the SDK docs (e.g. End(), TestBreak(), etc.).

              Best regards,

              Wilfried Behne

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                On 12/02/2012 at 19:10, xxxxxxxx wrote:

                I've been trying to understand this. But it's not making sense.
                If I end a thread using End(). It does not terminate the script code from running. It looks like all that does is acts like a switch to toggle the TestBreak() function from False- to- True:

                import c4d  
                  
                class MyThread(c4d.threading.C4DThread) :  
                  
                  def Main(self) :  
                      i=0  
                      while i<20:  
                          print i  
                          if self.TestBreak() : print "Thread Stopped"  #TestBreak is a Boolean "False" value until triggered "True" when the thread is stopped  
                          if i>15:  
                              print "Stop"       
                              self.End(wait=True)                      #Triggers the thread to stop  
                              #return                                  #Use this to stop the script from running any further  
                          i=i+1  
                  
                thread = MyThread()  
                thread.Start()
                

                The only way I can see of using threads to terminate a script is by using it to control a return.
                Is this correct?

                Here's something else that's strange to me.
                Why does this code only return the numbers between 3001-3999?
                Why doesn't it print the numbers 0 - 4000?

                import c4d  
                  
                class MyThread(c4d.threading.C4DThread) :  
                  
                  def Main(self) :  
                      for i in xrange(0, 4000) : #Only returns the numbers 3001-3999!?  
                          print i  
                  
                thread = MyThread()  
                thread.Start()
                

                Why it the threading forcing the print function to only return a thousand numbers?

                -ScottA

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                  On 13/02/2012 at 01:00, xxxxxxxx wrote:

                  Originally posted by xxxxxxxx

                  I've been trying to understand this. But it's not making sense.If I end a thread using End() [...]

                  The main thread does:
                  - interaction with the GUI (drawing, keyboard input, etc.)
                  - Spawns treads (by calling the Start() method)
                  - Tells the spawned threads that they should stop (by calling the End() method for the spawned threads)

                  The spawned tread:
                  - checks via TestBreak(), if it should stop
                  - terminates by returning from its Main() method

                  Best regards,

                  Wilfried Behne

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                    On 13/02/2012 at 04:41, xxxxxxxx wrote:

                    @wbeh: But how would I then implement reactin on user-input in a thread? The documentation does even point out that you can.

                    _<_dt id="c4dthread.testdbreak"_>_ `>Originally posted by xxxxxxxx

                    C4DThread.TestDBreak`( self )

                    Override this to add user breaks such as pressing ESC. This function is called by TestBreak().
                    _="field-"=""> Return type:| bool
                    Returns:| True if processing should be terminated, otherwise <_<_t_>_ng>False**.

                    @ScottA: You must exit the thread yourself.

                    def Main(self) :  
                      for ... :  
                            if self.TestBreak() :  
                              print "Quitting thread."  
                              break # or return, or whatever to quit the loop and / or the function
                    

                    -Niklas

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                      On 13/02/2012 at 06:17, xxxxxxxx wrote:

                      Originally posted by xxxxxxxx

                      @wbeh: But how would I then implement reactin on user-input in a thread? The documentation does even point out that you [...]

                      Again: You DON'T do any GUI interaction in a spawned thread. In the spawned thread you either work, react to TestBreak() or you leave the thread because your work is done.

                      What you can do when overriding TestDBreak is something like this:

                      //----------------------------------------------------------------------------------------
                      // Break function for the thread. A break will be signalled if the thread was requested to
                      // stop or if the current task takes too much time.
                      // Function result:          -
                      //----------------------------------------------------------------------------------------
                      Bool BackgroundThread::TestDBreak( void )
                      {
                          if ( please_suspend )                                           // stop it?
                            return( TRUE );

                      if ( in_action )                                                  // currently doing something?
                          {
                            LONG     current;
                            LONG     duration;
                            current = GeGetTimer();                                // this is the time when the current action started
                            duration = current - action_start;
                            if ( duration > 1000 )
                            {
                              time_out = FALSE;
                            }

                      if (( duration / 1000 ) > MySettings::GetUserSelectableTimeout())
                            {
                              time_out = TRUE;
                              return( TRUE );
                            }
                          }
                          return( FALSE );
                      }

                      Best regards,

                      Wilfried Behne

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                        On 13/02/2012 at 08:39, xxxxxxxx wrote:

                        Thanks a lot guys.
                        I now understand that threads don't stop running scripts. But they can be used as tests to determine when to execute a return, which in turn will stop the running script.

                        But what's up with the strange returns I get when using a for loop inside a thread?
                        Why do I only get a thousand numbers from my print statement?
                        I don't understand why that's happening when I run a for loop inside of a thread class?

                        Here's another version that also only prints out a thousand numbers:

                        import c4d  
                          
                        class MyThread(c4d.threading.C4DThread) :  
                          
                          def Main(self) :  
                              for i in xrange(0, 4000) :  
                                  self.End()  
                                  self.TestBreak()  
                                  if self.TestBreak() :  
                                      print i  
                          
                        thread = MyThread()  
                        thread.Start()
                        

                        -ScottA

                        1 Reply Last reply Reply Quote 0
                        • H
                          Helper
                          last edited by

                          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                          On 13/02/2012 at 09:34, xxxxxxxx wrote:

                          Originally posted by xxxxxxxx

                          But what's up with the strange returns I get when using a for loop inside a thread?
                          Why do I only get a thousand numbers from my print statement?
                          I don't understand why that's happening when I run a for loop inside of a thread class?

                          The console has a buffer of one thousand lines. This is why you only get the latest thousand numbers.

                          1 Reply Last reply Reply Quote 0
                          • H
                            Helper
                            last edited by

                            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                            On 13/02/2012 at 10:47, xxxxxxxx wrote:

                            Not sure if I understand what that means Yannick.

                            The "for" loop generates print results starting from 0+ when used in the "main" thread.
                            But only 1000 values when used inside of a custom thread.
                            You say this is due to a console buffer limit. But I don't get the connection there.

                            I guess it really doesn't matter if I understand how the console buffer works.
                            I just need to know if my loops will still work the same way in threads (starting from zero+) as they work in the main thread.
                            Should I  just take it on faith that they work the same. Even though I can't use the print function to see the entire output values?

                            -ScottA

                            1 Reply Last reply Reply Quote 0
                            • H
                              Helper
                              last edited by

                              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                              On 13/02/2012 at 11:20, xxxxxxxx wrote:

                              @Scott:

                              Imagine you have printed exactly 1000 lines to the console.

                              for i in xrange(1000) :  
                                print "Current:", i
                              

                              If you now print another one, the first line, which contains the string Current: 0, will be erased.

                              Next, why are you calling C4DThread.End() within the loop? It is intended to be used outside of the thread to notify you, while looping in the main, the thread should now exit.

                              import c4d  
                              import time  
                                
                              class MyThread(c4d.threading.C4DThread) :  
                                
                                def Main(self) :  
                                    for i in xrange(100) :  
                                        if self.TestBreak() :  
                                            print "MyThread.TestBreak() returned True, leaving the loop.."  
                                            break  
                                        print "Current:", i  
                                        time.sleep(1/25.)  
                                
                              def main() :  
                                thread = MyThread()  
                                thread.Start()  
                                time.sleep(1)  
                                thread.End()  
                                
                              main()
                              

                              As expected, this code runs until frame 25 (maybe 24 or 26, that depends on the machine) and then exits because we told it to exit after we've waited for a second.

                              Current: 0  
                              Current: 1  
                              Current: 2  
                              Current: 3  
                              Current: 4  
                              Current: 5  
                              Current: 6  
                              Current: 7  
                              Current: 8  
                              Current: 9  
                              Current: 10  
                              Current: 11  
                              Current: 12  
                              Current: 13  
                              Current: 14  
                              Current: 15  
                              Current: 16  
                              Current: 17  
                              Current: 18  
                              Current: 19  
                              Current: 20  
                              Current: 21  
                              Current: 22  
                              Current: 23  
                              Current: 24  
                              Current: 25  
                              MyThread.TestBreak() returned True, leaving the loop..
                              

                              -Niklas

                              PS: What is up with my posts? I see scrollbars for it, never seen that before here..

                              1 Reply Last reply Reply Quote 0
                              • H
                                Helper
                                last edited by

                                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                On 13/02/2012 at 12:26, xxxxxxxx wrote:

                                Thanks for correcting me on that Nux.
                                Now I see why it was returning only the last 1000 numbers the way I was using it.

                                Thanks to everyone for the great information in this thread... um...about threading.😂
                                Lots of good information in here.

                                -ScottA

                                1 Reply Last reply Reply Quote 0
                                • H
                                  Helper
                                  last edited by

                                  On 05/10/2017 at 21:44, xxxxxxxx wrote:

                                  Check this one...Python thread basics

                                  1 Reply Last reply Reply Quote 0
                                  • First post
                                    Last post