Recent

Author Topic: [WILL NOT IMPLEMENT]Killing a thread: How to  (Read 6456 times)

taazz

  • Hero Member
  • *****
  • Posts: 5368
[WILL NOT IMPLEMENT]Killing a thread: How to
« on: September 19, 2012, 07:55:23 pm »
I need to make sure that a thread I am creating use TThread class after a specified time will be stopped regardless if it has finished the job given or not. there is only one requirement, since this thread will try to create a condition that in an object method an infinite loop will be surfaced, there is no way to check for terminated and simple exit, I need to forcible stop the threads execution and kill it from memory.

As I said this is only a test to test one of my assumptions and it will never be executed again so no need to worry about memory leaks or half destroyed objects.

Any help would be appreciated.
regards
Jo
« Last Edit: September 20, 2012, 06:50:46 pm by taazz »
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4695
  • I like bugs.
Re: Killing a thread: How to
« Reply #1 on: September 19, 2012, 08:36:51 pm »
I need to make sure that a thread I am creating use TThread class after a specified time will be stopped regardless if it has finished the job given or not. there is only one requirement, since this thread will try to create a condition that in an object method an infinite loop will be surfaced, there is no way to check for terminated and simple exit, I need to forcible stop the threads execution and kill it from memory.

I don't think it is possible using LCL classes/methods. You need to call OS level functions.
I don't know your code but usually you can check the Terminated state inside any loop, including an infinite loop you mentioned.

Juha
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Killing a thread: How to
« Reply #2 on: September 19, 2012, 08:50:58 pm »
I don't think it is possible using LCL classes/methods. You need to call OS level functions.
I don't know your code but usually you can check the Terminated state inside any loop, including an infinite loop you mentioned.

Juha

my code goes like this.
Code: [Select]
TMuThread.Execute;
var
  MyTestObject : TMyObject;
begin
   MyTestObject := TMyObject.Create(nil);
   Try
     //Set up properties
    // Make some modifications to protected data to hope over existing rules.
    // Get a Value that indirectly calls an internal method.
    // get a Second Value for the same reason.
    Terminate;
   Finally
     MyTestObject.Free;
   end;
end;

Procedure Test;
var
  TestThread :TMyThread;
  ST, TK  : Cardinal;
begin
  TestThread := TmyThread.Create(True);
  Try
     TestThread.Resume;
     ST := GetTickcount;
     Repeat
        TK := GetTickCount - ST;
     Until TestThread.Terminated or (TK > 60000);
     If not TestThread.Terminated then //Raise Exception.Create('Infinite loop');
     else //Show data retreived.
  Finally
    TestThread.Free;
  end;
end;

as you can see the infinite loop is triggered in an other component under a specific conditions which can never be raised based on my running analysis. So I want to make sure that when this code is removed the reasons why are fully documented.

I don't mind using OS function I'm on windows 7 32bits if you can give me a hint.

Appreciate your time.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Killing a thread: How to
« Reply #3 on: September 20, 2012, 10:08:56 am »
Code: [Select]
     Repeat
        TK := GetTickCount - ST;
     Until TestThread.Terminated or (TK > 60000);
That is almost a thread in itself, and code style usually unrecommended. Unsure of this, but it might not give your behind-running-thread actual time at all. Try putting Application.Processmessages; inside the repeat..until.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4695
  • I like bugs.
Re: Killing a thread: How to
« Reply #4 on: September 20, 2012, 05:01:06 pm »
I don't know enough about Win API to help you there, sorry.

I wonder what you did with protected data etc., but it sounds like you are making a big hack.
You really should detect the infinite loop inside the thread itself. You know where the loops are. Just test the tick count inside them.

BTW, your main thread loop has one more problem: it hogs CPU time.
You could add a Sleep there:

Code: [Select]
Repeat
  Sleep(100);  // or Sleep(1000);
  TK := GetTickCount - ST;
Until TestThread.Terminated or (TK > 60000);


Regards,
Juha
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Killing a thread: How to
« Reply #5 on: September 20, 2012, 06:50:04 pm »
Code: [Select]
     Repeat
        TK := GetTickCount - ST;
     Until TestThread.Terminated or (TK > 60000);
That is almost a thread in itself, and code style usually unrecommended. Unsure of this, but it might not give your behind-running-thread actual time at all. Try putting Application.Processmessages; inside the repeat..until.

1) my thread just parses 2 strings with length of 120 characters a minute is way to much time to walk from start to end for the string.
2) I do not want any application.process messages in there. I wanted to make sure that the user interface remains frozen for the duration of a minute or what ever I set the margin to be. It was to be used only by me just to find out if I'm right.

I don't know enough about Win API to help you there, sorry.

I wonder what you did with protected data etc., but it sounds like you are making a big hack.

No worries thank you for taking the time to answer and yes it was a unstable and unpredictable hack just to confirm if I'm right on my assumptions which I was.

You really should detect the infinite loop inside the thread itself.
You know where the loops are. Just test the tick count inside them.

That would require to add code to the object it self and I did not want to touch it at that point, in case I have missed something else that goes on in there and my code either broke or fixed something by chance.

BTW, your main thread loop has one more problem: it hogs CPU time.
You could add a Sleep there:

Code: [Select]
Repeat
  Sleep(100);  // or Sleep(1000);
  TK := GetTickCount - ST;
Until TestThread.Terminated or (TK > 60000);


Thank you I hit hard on it too, I'll keep that in mind.

In any case I quickly abandon this and used the debugger and break points /break point count to stop the program from inside the ide.
I have my answer.

thank you all for your time.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: [WILL NOT IMPLEMENT]Killing a thread: How to
« Reply #6 on: September 20, 2012, 08:45:43 pm »
Although you have sorted this,. 
A few little points..

First, don't bother checking for Terminated, this is just a boolean that your meant to set.  And if your not setting it, then your bit of code will always just infinite loop.

Here is a snippet of code that might be what your after, also I think it's cross platform as it doesn't require any Win specific uses clause.

Code: [Select]
    //wait 6 seconds for thread to finish,
    if WaitForThreadTerminate(TestThread.handle,6000) <> 0 then
      //didn't finish, lets kill it.
      KillThread(TestThread.handle);     

 

TinyPortal © 2005-2018