Thread End and TestBreak

On 23/11/2017 at 02:50, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R18 
Platform:   Windows  ;   
Language(s) :     C++  ;


I have some issues with a procedure I am developing that is intended to run multithreaded and I would like to clarify some things.

Lets say I have a C4DThread named thread_a that runs a while(1) loop in its Main.
Even If I call thread_a->End(), the thread will keep running unless I manually break the loop by checking TestBreak() (is that correct ? ).

Even when End is called for my custom C4DThread, I don't wont to stop the execution unless I finish the calculation. So, I ignore the result of any TestBreak call. 
Is there any limitation after End is called ?

Thank you.

On 23/11/2017 at 03:24, xxxxxxxx wrote:

Wait an official reply. But you are right in your assomption.

If the thread does not check for TestBreak() then this function will not return until the thread has finished and this might get into a deadlock situation.

About what limitation I can't tell. Since TestBreak() return true only when Cinema 4D itself need to close, or you explicitly call End(false), so I guess is not a good bet to play with a thread when it's host need to close, and have probably already close all others threads it manage :p

Didn't know your design, but idealy you should never call End() by yourself.
I mean if you need to stop on some condition => C4dThread.TestDBreak() is done for that. If you need to call End() that mean you get some syncrhonization problems and should try to syncronize everythings using differents lock system wich fit the best for your need.

So personally I let TestBreak() for all "sys" / c4d call of End, so I'm sure when user quit c4d he will not wait forever just for have your thread finnished. Then everythings will close (wasting time).
And I guess is how Cinema 4D is designed TestBreak is when you absolutly need to return and TestDBreak let you decide if you should return or not. At Least is like that I understand it and I may be wrong.

On 23/11/2017 at 06:47, xxxxxxxx wrote:

Hello and thank you for your suggestions !

The API says on C4DThread's Lock:

"Tries and locks. If the semaphore is already locked, this will also wait for access.
If a thread is pass it will also check the BaseThread::TestBreak() for the thread and exit with false if a user break is detected. Returns false if semaphore already was locked, otherwise true. "

Does it also wait in Lock if the passing thread's TestBreak is true ?

Thank you.

On 24/11/2017 at 09:01, xxxxxxxx wrote:

I'm not sure I understand the question. I just tested it and it works as described in the documentation. If a thread is passed to Semaphore::Lock(), Lock() will return with false if C4DThread::TestBreak() of the passed thread returns true. No lock will be acquired in this case. After all that's the whole point in passing a thread to Semaphore::Lock(), so it can be interrupted, when the thread is supposed to be terminated.

Edit: Sorry, I was in the wrong thread...

On 24/11/2017 at 09:18, xxxxxxxx wrote:

Maybe I should also point to our Threading Overview and it's child articles.

For the initial question: It's absolutely fine to call C4DThread::End(), if you want to abort a thread. But you have to be aware, this can not interrupt the work a thread is doing. Instead it will just trigger the break condition, therefore the thread needs to (and should) make use of C4DThread::TestBreak() so it can be aborted.
Also pay attention to the parameter of End(). In any case the thread needs to run through some code (run until TestBreak() condition and then exit the function) before it is finally finished/terminated. The wait parameter lets you cater for this.

As gr4ph0s said, it's not good practice or design to have a thread not using TestBreak().