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: 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
-
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() 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.
-
@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) 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
-
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
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?
-
Hi Mafster, thanks for following up.
The documentation here properly indicates that passing no parameter to
Wait()
is passingTrue
.
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