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

    Unable to kill my C4DThread

    Cinema 4D SDK
    3
    8
    1.5k
    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.
    • M
      mafster
      last edited by mafster

      As in the title, I've got a BaseThread running which i think doesnt die once process is finished.

      The thread runs an ffmpeg call via subprocess.wait() (also tried communicate()). Everything seems to work but after closing cinema4d i cant reopen it, in the task manager there is a c4d process still there taking minimal resources. If i kill that task i can then reopen c4d again. My guess is im not using the threads correctly and the thread stays round after the process is finished.

      My code below:
      note: self.data is added to the thread elsewhere. Suppose I could add in init as well.

      class CompileAVThread(c4d.threading.C4DThread):
      
          def Main(self):
      
              result = compile_av(**self.data)
      
              if result is True:
                  gui.MessageDialog('Export completed')
                  path = os.path.dirname(self.data['output'])
                  open_path(path)  # separate def that opens native os file browser at correct location
      
              else:
                  print('Something went wrong')
                  gui.MessageDialog('Failed')
      
              if self.TestBreak():
                  # Dont really get how TestBreak works..
                  print('Exiting thread please?')
                  return
      

      And the subprocess:

      p = subprocess.Popen(args=arg_list, shell=False)
      
      if p.wait() == 0:
          return True
      else:
          print "Failed - %s" % p.stdout.read()
          return False
      
      1 Reply Last reply Reply Quote 0
      • M
        mp5gosu
        last edited by

        How and where do you handle your thread? Do you use Thread.Wait()?

        M 1 Reply Last reply Reply Quote 0
        • M
          mafster @mp5gosu
          last edited by mafster

          @mp5gosu thanks for the reply. I use Thread.Start().

          I also run the thread from within a gui.GeDialog. Command() method

          def Command()
              self.thread = myThread.MyThread()
              self.thread.data = data  # Load some data in
          
              self.thread.Start()
          
          

          I'm guessing i may need to call End() somewhere? However this dialog closes after the thread starts. I figured the thread would be garbage collected once its done with its process.

          1 Reply Last reply Reply Quote 0
          • M
            mafster
            last edited by

            @mp5gosu I should also mention that i tried calling self.End() from within the thread which i had heard isnt good practice. But anyway...didnt work XD

            1 Reply Last reply Reply Quote 0
            • r_giganteR
              r_gigante
              last edited by

              Hi Mafster and thanks for reaching out us.

              With regard to your question, we've recently discussed a similar topic here and I do recommend having a look at.

              I've used the code below and I actually had Cinema being reactive whilst ffmpeg was running as well as having Cinema being gracefully closed at the end of the session.

              import c4d
              from c4d.threading import C4DThread
              
              import subprocess, sys
              
              
              class UserThread(C4DThread):
                def Main(self):
                  # call subprocess
                  cmd = ["/opt/local/sbin/ffmpeg", "<arg1>", "<arg2>", ..., "<argn>"]
                  proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                  pass
              
              def main():
                thread = UserThread()
                thread.Start()
                 # Wait until the main method is done
                thread.Wait(True)
              
              
              # Execute main()
              if __name__=='__main__':
                main()
              

              Am I missing something here?

              Cheers, Riccardo

              M 2 Replies Last reply Reply Quote 0
              • M
                mafster @r_gigante
                last edited by

                @r_gigante

                Thanks for the example. In my case this just causes C4d to freeze wile the process is running. Once its done then i get c4d back again.

                Strangely if i leave the bool argument out out from Wait() method it will error (Type error) but then the ffmpeg will still be running (as its running from the Start() method and c4d is responsive and also closes gracefully.

                This seems an entirely non-elegant and accidental way of finding a "solution" essentially using an error to give me the result i want. I accidentally left out the boolean argument, everything seemed to work and then checked the logs and realised the error.

                1 Reply Last reply Reply Quote 0
                • M
                  mafster @r_gigante
                  last edited by

                  @r_gigante By default thread.Wait() should pass in True?

                  I just had a thought because the thread.Wait() in my case is a property of self

                  self.thread.Wait()
                  

                  is it possible self is being passed in (as Python does) and its reading that as a the bool argument and so getting type Error?

                  1 Reply Last reply Reply Quote 0
                  • r_giganteR
                    r_gigante
                    last edited by

                    Hi Mafster, thanks for following up.

                    The documentation here properly indicates that passing no parameter to Wait() is passing True.
                    Long story short, this value is required in order to avoid Cinema being stuck on waiting for the thread to end.

                    Hoping this helps in solving the issue, give best.
                    Riccardo

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