Recent

Author Topic: Cannot run a process procedure in a thread  (Read 4529 times)

glubbish

  • Jr. Member
  • **
  • Posts: 66
Re: Cannot run a process procedure in a thread
« Reply #15 on: July 17, 2024, 11:01:46 am »
A few pointers.
- remove all the thread related code, seriously
#works fine without the thread code. Been running for years.
- the way you add parameters to tprocess seems very wrong to me (I could not get that to work).
#ok, but it works for me. There is probably no reason to break it down into sections, but its easier for me to read.
- why do you pass along 4 filenames to mkvmerge ? (should be one for result/output, one for original movie, one for subtitle)
# there are only 3 filenames, the tmpfile (output) and 2 input (mkv and srt).
- if you run mkvmerge in quiet mode then mkvmerge will be ... well quiet (no textual feedback unless an actual error occurs). Therefor your percentage update implementation will happen only one time
# I use the v (verbose) instead of quiet when testing. it takes several minutes to run
- even if you omit the quiet mode option there will not be much feedback
# very true. But it does open a window that signifies that its running the process, and I can close it to end it early.
- you can get more feedback by adding the option --gui-mode which returns percentages but adding a srt to file will happen very quick and not many feedback is provided (only a couple of percentage feedback lines are
returned depending on the lenght of your video)
#thanks. will add this when debugging.
- I am confused by the tproces running loop and the corresponding percentage calculations
#sorry, I am not surprised. It is a hack based on the size of the file divided by the number of sleeps that occurred in one test. 
#not too concerned about this, I can make it better later

One variation of my program does work in a thread, but the current one fails on mythread.start. The only difference is the  stringgrid section, I pass a static parameter instead.
I intend to use the clues given about on the working program so I can get something acceptable going, so help may be a bit easier.

Attached the error I get.

TRon

  • Hero Member
  • *****
  • Posts: 3623
Re: Cannot run a process procedure in a thread
« Reply #16 on: July 17, 2024, 11:21:34 am »
A few pointers.
- remove all the thread related code, seriously
#works fine without the thread code. Been running for years.
But it is present in your example from post #7 and there it is unnecessary.

Quote
- the way you add parameters to tprocess seems very wrong to me (I could not get that to work).
#ok, but it works for me. There is probably no reason to break it down into sections, but its easier for me to read.
Some tools are very finicky and so is mkvmerge (at least on Linux)

Quote

- why do you pass along 4 filenames to mkvmerge ? (should be one for result/output, one for original movie, one for subtitle)
# there are only 3 filenames, the tmpfile (output) and 2 input (mkv and srt).


Then I must be seeing something wrong in post #7 unit main routine DoTheWork


Code: Pascal  [Select][+][-]
  1.     MyParameter := ' -q -o "' + tmpfile + '" "';  // <- this is #1 (outputfile)
  2.     MyParameter := MyParameter + IncludeTrailingPathDelimiter(Form1.Display.Cells[0, i]); // <- here is #2 and I do not even know for sure what this one is, probably the srt file
  3.     MyParameter := MyParameter + Form1.Display.Cells[1, i]; // <- this is #3, the original video file
  4.     MyParameter := MyParameter + '" --language 0:eng --track-name 0:English "';
  5.     MyParameter := MyParameter + IncludeTrailingPathDelimiter(Form1.Display.Cells[0, i]); // <- here is #4, same as #2
  6.     MyParameter := MyParameter + Form1.Display.Cells[2, i]; // <- here is #5, the subtitle file
  7.     MyParameter := MyParameter + '"';
  8.  
edit: nvm. The file search implementation blindsided me. Cells[0, i] is the directory location.

Quote
- even if you omit the quiet mode option there will not be much feedback
# very true. But it does open a window that signifies that its running the process, and I can close it to end it early.
Platform Windows ?

Quote
#sorry, I am not surprised. It is a hack based on the size of the file divided by the number of sleeps that occurred in one test. 
#not too concerned about this, I can make it better later
Ok, thx. will do.

Quote
One variation of my program does work in a thread, but the current one fails on mythread.start.
Yeah but the whole point is that it isn't necessary. Ofc you can if you want to.

Quote
Attached the error I get.
Attempting to read something from somewhere you are not allowed usually indicates an unintialized class. Use the debugger and/or produce a stack-trace with line-numbers is the best advice I am able to give atm (e.g. your guess is as good as mine but do keep in mind that you are not allowed to touch anything inside a thread which isn't part of the thread context).
« Last Edit: July 17, 2024, 11:44:46 am by TRon »
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

cdbc

  • Hero Member
  • *****
  • Posts: 1646
    • http://www.cdbc.dk
Re: Cannot run a process procedure in a thread
« Reply #17 on: July 17, 2024, 03:28:59 pm »
Hi
Quote
but the current one fails on mythread.start.
instead of:
Code: Pascal  [Select][+][-]
  1. MyThread.Create(True);
you have to do:
Code: Pascal  [Select][+][-]
  1. MyThread:= TMyThread.Create(True);  // <-- HERE
  2. //  - - - - - - ^ - ^ - ^ ^ - ^ .
Regards Benny
« Last Edit: July 17, 2024, 03:30:37 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

glubbish

  • Jr. Member
  • **
  • Posts: 66
Re: Cannot run a process procedure in a thread
« Reply #18 on: July 18, 2024, 12:02:26 am »
Thanks cdbc,
That was my current problem. My eyes kept skipping over that part.

I did read the 'homework' but a lot of it was beyond my current understanding.
The whole point of this (windows) implementation is to use a thread, something I thought I should try. Had no idea how difficult it was.

My plan is to follow your example to at least make it more acceptable, I believe I will learn a bit just doing that.

cdbc

  • Hero Member
  • *****
  • Posts: 1646
    • http://www.cdbc.dk
Re: Cannot run a process procedure in a thread
« Reply #19 on: July 18, 2024, 07:38:35 am »
Hi
Ok, then here's a helping hand, in form of 2 little gems:
1) for protecting your data against simultaneous access:
Code: Pascal  [Select][+][-]
  1. var rws: IReadWriteSync; // com-object for convenience
  2. begin
  3.   rws:= TSimpleRWSync.Create;
  4. ...
  5. // no need to free the above, it's refcounted. else 'rws:= nil;' = free
  6. // if you make it a field of your form/class then 'fRws' will live as long as
  7. // your form/class.
  8.  
2) for communicating messages and data between threads:
in unit 'contnrs', you'll find lists, hashmaps, queues & stacks...
which you only need to protect with the above 'IReadWriteSync', to have threadsafe comms.
Threading *is* advanced programming, so be thorough and __don't__ cut corners!!! ...Deadlocks *will* bring your computer to its knees.
Have fun
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

glubbish

  • Jr. Member
  • **
  • Posts: 66
Re: Cannot run a process procedure in a thread
« Reply #20 on: July 19, 2024, 06:56:38 am »
Have made the program more like the example given.

Currently trying to use an OnTerminate, tried several versions, but currently like the homework example https://www.seti.net/engineering/threads/chap4/source8.php

It will not compile, says: main.pas(244,36) Error: Identifier not found "HandleTerminate"

I am certainly missing something, but I cannot figure out what.

cdbc

  • Hero Member
  • *****
  • Posts: 1646
    • http://www.cdbc.dk
Re: Cannot run a process procedure in a thread
« Reply #21 on: July 19, 2024, 10:57:16 am »
Hi
"HandleTerminate" is an event-handler, you implement in your TForm like this:
Code: Pascal  [Select][+][-]
  1. type
  2.   TForm1 = class(TForm)
  3. ...
  4.   private
  5. ...
  6.   public
  7.     Procedure HandleTerminate(aSender: TObject);
  8. ...
  9. /// and the implement like this:
  10. Procedure TForm1.HandleTerminate(aSender: TObject);
  11. begin
  12.   // do your stuff from example here
  13. end;
  14.  
and to use:
Code: Pascal  [Select][+][-]
  1. ...
  2.   MyThread:= TMyThread.Create(True);
  3.   MyThread.OnTerminate:= @HandleTermminate; //<- connect it
  4. ...
  5.  
This is just right off the bat, to get you going, I'll have a look at your code, a little bit later, got some chores to do  :D
HTH
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

cdbc

  • Hero Member
  • *****
  • Posts: 1646
    • http://www.cdbc.dk
Re: Cannot run a process procedure in a thread
« Reply #22 on: July 19, 2024, 11:13:14 am »
Hi
The code you've uploaded now, is the same useless shijt as the last one!
What part of "NO GUI STUFF IN WORKER-THREAD!" is not to understand?!?
very time-wasted regards /b

edit: ...and practice 'thread-programming' on a simpler project/undertaking, until you understand the bare minimum!
« Last Edit: July 19, 2024, 11:17:33 am by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

glubbish

  • Jr. Member
  • **
  • Posts: 66
Re: Cannot run a process procedure in a thread
« Reply #23 on: July 19, 2024, 11:31:27 am »
You keep saying no gui stuff in the worker thread, but never explain what that is.
I cannot see it.
The worker thread is the code in procedure TMyThread.Execute;  I thought.

I already tried doing it the way you suggested and had the same issue, so thought I should use what was in the homework example, as it has been touted as correct code.

bytebites

  • Hero Member
  • *****
  • Posts: 681

cdbc

  • Hero Member
  • *****
  • Posts: 1646
    • http://www.cdbc.dk
Re: Cannot run a process procedure in a thread
« Reply #25 on: July 19, 2024, 11:49:01 am »
Hi
Here:
Code: Pascal  [Select][+][-]
  1. procedure TMyThread.ShowProgress(Progress: integer);
  2. begin
  3.   Form1.Display.Cells[3, CurrentRow] := 'Processing (' + IntToStr(Progress) + '%)';
  4. end;//^  
and here:
Code: Pascal  [Select][+][-]
  1. // TMyThread.Execute
  2. ...
  3.   case AProcess.ExitCode of   // Check for errors
  4.     1: begin                  // This is a warning. Display it and choose if we continue If timestamp out of order, then fix manually and run again.
  5.       for i := 0 to AStringList.Count - 1 do if MessageDlg('Continue?', AStringList.Strings[i], mtConfirmation, [mbYes, mbNo], 0) = mrNo then
  6.         begin
  7.           AStringList.Free;
  8.           AProcess.Free;
  9.           halt(AProcess.ExitCode);
  10.         end;
  11.     end;
  12.     2: begin  // This is an error. Display it, but no choice to continue. Also free
  13.       for i := 0 to AStringList.Count - 1 do ShowMessage(AStringList.Strings[i]);
  14.       AStringList.Free;
  15.       AProcess.Free;
  16.       halt(AProcess.ExitCode);
  17.     end;
  18.   end;
  19. ...
  20.  
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

glubbish

  • Jr. Member
  • **
  • Posts: 66
Re: Cannot run a process procedure in a thread
« Reply #26 on: July 19, 2024, 11:53:31 am »
Hi Benny,
Something weird is going on here.

The procedure showprogress you copied is commented out in the current program

The case you documented next looks like this in the latest program:
Code: Pascal  [Select][+][-]
  1.   case AProcess.ExitCode of   // Check for errors
  2.     1: begin                  // This is a warning.
  3.       AStringList.Free;
  4.       AProcess.Free;
  5.       halt(AProcess.ExitCode);
  6.     end;
  7.     2: begin  // This is an error. Display it, but no choice to continue. Also free
  8.       for i := 0 to AStringList.Count - 1 do
  9.       begin
  10.         MyMessage := AStringList.Strings[i];
  11.         Synchronize(@ShowMyMessage);
  12.       end;
  13.       AStringList.Free;
  14.       AProcess.Free;
  15.       halt(AProcess.ExitCode);
  16.     end;
  17.   end;

ShowProgress in the current program looks like this:

Code: Pascal  [Select][+][-]
  1. procedure TMyThread.ShowProgress(Progress: integer); // <-- HERE
  2. begin
  3.   PostMessage(frmHandle, LM_PROGRESS, -1, Progress);
  4. end;      
  5.  
« Last Edit: July 19, 2024, 11:55:25 am by glubbish »

glubbish

  • Jr. Member
  • **
  • Posts: 66
Re: Cannot run a process procedure in a thread
« Reply #27 on: July 19, 2024, 12:02:06 pm »
Ok, I downloaded it myself, and it looks like the first one I uploaded.
I am going to rename the zip and try again, I will download and make sure its right.

edit: this one looks ok.

cdbc

  • Hero Member
  • *****
  • Posts: 1646
    • http://www.cdbc.dk
Re: Cannot run a process procedure in a thread
« Reply #28 on: July 19, 2024, 02:27:06 pm »
Hi
Try this:
Code: Pascal  [Select][+][-]
  1.     ...
  2.     MyParameter := MyParameter + '"';
  3.     Form1.Display.repaint;
  4.     MyThread[i]                 := TMyThread.Create(True);
  5.     MyThread[i].FreeOnTerminate := True;
  6.     MyThread[i].OnTerminate     := @Form1.HandleTerminate; //<- HERE
  7.     MyRow                       := i; { you're in a procedure NOT a method of TForm1 }
  8.     MyThread[i].Start;
  9.     ...  
Here it compile with fpc 3.2.2
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

glubbish

  • Jr. Member
  • **
  • Posts: 66
Re: Cannot run a process procedure in a thread
« Reply #29 on: July 20, 2024, 01:35:51 am »
Thanks Benny.
That does indeed compile.
In all the examples I could find, that format did not exist.

Unfortunately I don't think I am going to be able to do as I planned as I cannot use 'if MyThread.CheckTerminated then   ' in the onterminate procedure

 

TinyPortal © 2005-2018