Solved Unable to kill my C4DThread

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: 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(**

        if result is True:
            gui.MessageDialog('Export completed')
            path = os.path.dirname(['output'])
            open_path(path)  # separate def that opens native os file browser at correct location

            print('Something went wrong')

        if self.TestBreak():
            # Dont really get how TestBreak works..
            print('Exiting thread please?')

And the subprocess:

p = subprocess.Popen(args=arg_list, shell=False)

if p.wait() == 0:
    return True
    print "Failed - %s" %
    return False

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

@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() = data  # Load some data in


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.

@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

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)

def main():
  thread = UserThread()
   # Wait until the main method is done

# Execute main()
if __name__=='__main__':

Am I missing something here?

Cheers, Riccardo


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.

@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


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?

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.