Recent

Author Topic: thread (Resolvido)  (Read 5142 times)

anderbelluno

  • New Member
  • *
  • Posts: 39
thread (Resolvido)
« on: June 22, 2017, 10:32:38 pm »
https://www.youtube.com/watch?v=olsdlSQ5Lt0

Segui seu video e fiz exatamente como no video, mas não funciona minha thread.
Não gera nenhum erro, simplesmente o showmessage aparece somente após a thread concluir.
estou usando o win10 64bit e o Lazarus 1.6.4
oque sera que acontece?
Muito Obrigado.
Anderson
« Last Edit: June 26, 2017, 11:03:39 am by anderbelluno »

Thaddy

  • Hero Member
  • *****
  • Posts: 14164
  • Probably until I exterminate Putin.
Re: thread
« Reply #1 on: June 22, 2017, 11:28:46 pm »
I stopped watching after about three seconds because it looks like BASIC:
- Everything is UPPERCASED...
- And you count from 1... Real programmers count from zero  8-)

Nice try! Video is of good quality, but you can skip a bit.
« Last Edit: June 22, 2017, 11:33:23 pm by Thaddy »
Specialize a type, not a var.

rvk

  • Hero Member
  • *****
  • Posts: 6056
Re: thread
« Reply #2 on: June 22, 2017, 11:46:25 pm »
I stopped watching after about three seconds because it looks like BASIC:
- Everything is UPPERCASED...
- And you count from 1... Real programmers count from zero  8-)

Nice try! Video is of good quality, but you can skip a bit.
Thaddy, did you read the question?

I don't think the video is from Anderson.
He just asked a question about it.

JD

  • Hero Member
  • *****
  • Posts: 1848
Re: thread
« Reply #3 on: June 23, 2017, 12:27:20 am »
I stopped watching after about three seconds because it looks like BASIC:
- Everything is UPPERCASED...
- And you count from 1... Real programmers count from zero  8-)

Nice try! Video is of good quality, but you can skip a bit.

 :D :D :D :D :D
Windows - Lazarus 2.1/FPC 3.2 (built using fpcupdeluxe),
Linux Mint - Lazarus 2.1/FPC 3.2 (built using fpcupdeluxe)

mORMot; Zeos 8; SQLite, PostgreSQL & MariaDB; VirtualTreeView

kapibara

  • Hero Member
  • *****
  • Posts: 610
Re: thread
« Reply #4 on: June 23, 2017, 12:47:52 am »
Você precisa disso no laço. Ou então, o loop roubará todo o poder da janela principal e o showmessage não será exibido até que o loop termine.

Code: Pascal  [Select][+][-]
  1. Sleep(1);

Olhe para demonstração..

He asked:

"I followed your video and did exactly as in the video, but my thread does not work.
It does not generate any errors, simply the showmessage appears only after the thread completes.
I'm using win10 64bit and Lazarus 1.6.4
What happens?"

And I said: You need this in the loop. Or else the loop will steal all power from the main window, and showmessage won't be showed until the loop ends.
« Last Edit: June 23, 2017, 02:17:32 am by kapibara »
Lazarus trunk / fpc 3.2.2 / Kubuntu 22.04 - 64 bit

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11352
  • FPC developer.
Re: thread
« Reply #5 on: June 23, 2017, 11:47:31 am »
That video is basically a BAD example of threading, not a good one.

It synchronizes all operations to the mainthread, and in fact /everything/ happens in the mainthread, so the only effect that threading has in this case is to increase total overhead, rather than improve the performance.

The good approach would be to rewrite the algorithm so that it works in the thread, and only updates the gui 10-100 times per second with queue or synchronize.

However since the example doesn't do anything except GUI update that is hard to realize here. Show more of what you really want to do, and less videos. (which are overrated anyway IMHO)
« Last Edit: June 23, 2017, 11:49:56 am by marcov »

anderbelluno

  • New Member
  • *
  • Posts: 39
Re: thread
« Reply #6 on: June 23, 2017, 03:10:12 pm »
Obrigado a todos por responder.
Kapibara, vou fazer uns testes aqui como vc disse.
Gostaria de pedir como seria um bom exemplo de thread.
Na verdade estou montando um programa que verifica um arquivo no server, quando sofre alterações devo ler este arquivo, atualizar o banco de dados com as novas informações e devo também verificar se um pc está ligado.

kapibara

  • Hero Member
  • *****
  • Posts: 610
Re: thread
« Reply #7 on: June 24, 2017, 12:17:44 am »
"Here's a demo along those lines. The filecheck interval is controlled by an RTLevent instead of just a sleep() so the thread can finish faster. Is it an SQL database you will update?"

Aqui está uma demonstração nesse sentido. O intervalo de teste é controlado por um RTLevent em vez de apenas um sleep (), de modo que o thread pode terminar mais rápido. É um banco de dados SQL que você irá atualizar?

Quote
Thank you all for responding.
Kapibara, I'm going to run tests here like you said.
I would like to ask how would be a good example of thread.
Actually I am putting together a program that checks a file on the server, when I undergo changes I must read this file, update the database with the new information and I should also check if a pc is connected.

If anyone has ideas for improving the code below, pls go ahead. :-)

NOTE: inside project1.lpr I have uncommented unit cthreads because I use Linux, you might have to comment it out if you are a windows user.

EDIT: I updated the example to check file changes.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   ComCtrls, ExtCtrls, EditBtn, Spin;
  10.  
  11. type
  12.  
  13.   { TMyThread }
  14.  
  15.   TMyThread = class(TThread)
  16.   private
  17.     FLastFileAge: Integer;
  18.     FLogMessage: string;
  19.     FSleepEvent: PRTLEvent;
  20.     procedure Log(AValue: string);
  21.   public
  22.     MonitorInterval: Integer;
  23.     procedure SetFileAge(AValue: Integer);
  24.     procedure DoLog;  //Dispatch method
  25.     function CheckFileChange: Boolean;
  26.     function UpdateDatabase: Boolean;
  27.     procedure Execute; override;
  28.     procedure WakeUp;
  29.     constructor Create({%H-}CreateSuspended: Boolean; const {%H-}StackSize: SizeUInt=DefaultStackSize);
  30.   end;
  31.  
  32.   { TForm1 }
  33.  
  34.   TForm1 = class(TForm)
  35.     btnMonitor: TButton;
  36.     FileToCheck: TFileNameEdit;
  37.     Label1: TLabel;
  38.     Label2: TLabel;
  39.     lblInterval: TLabel;
  40.     lbLog: TListBox;
  41.     spinInterval: TSpinEdit;
  42.     procedure btnMonitorClick(Sender: TObject);
  43.     procedure FormCreate(Sender: TObject);
  44.   private
  45.     Thread: TMyThread;
  46.   public
  47.     procedure LogMessage(AValue: string);
  48.   end;
  49.  
  50. var
  51.   Form1: TForm1;
  52.  
  53. implementation
  54.  
  55. {$R *.lfm}
  56.  
  57. { TMyThread }
  58.  
  59. procedure TMyThread.Log(AValue: string);
  60. begin
  61.   FLogMessage:=AValue;
  62.   Synchronize(@DoLog); //Dispatch methods called by synchronize take no arguments
  63. end;
  64.  
  65. procedure TMyThread.SetFileAge(AValue: Integer);
  66. begin
  67.   FLastFileAge:= AValue;
  68. end;
  69.  
  70. procedure TMyThread.DoLog;
  71. begin
  72.     Form1.LogMessage(FLogMessage);
  73. end;
  74.  
  75. function TMyThread.CheckFileChange: Boolean;
  76. begin
  77.   Result:=False;
  78.   if FLastFileAge = FileAge(Form1.FileToCheck.FileName) then
  79.   begin
  80.     Log(TimeToStr(Now) + ': File not changed');
  81.   end
  82.   else
  83.   begin
  84.     FLastFileAge:= FileAge(Form1.FileToCheck.FileName);
  85.     Log(TimeToStr(Now) + ': File changed');
  86.   end
  87. end;
  88.  
  89. function TMyThread.UpdateDatabase: Boolean;
  90. begin
  91.   //Process file and update database here..
  92.   Result:=False;
  93.   Log(TimeToStr(Now) + ': Database updated');
  94. end;
  95.  
  96. procedure TMyThread.Execute;
  97. begin
  98.   while not Terminated do
  99.   begin
  100.     if CheckFileChange then
  101.       UpdateDatabase;
  102.     RTLeventWaitFor(FSleepEvent, MonitorInterval);
  103.   end;
  104.   RTLeventdestroy(FSleepEvent);
  105.   Log(TimeToStr(Now) + ': Monitoring stopped');
  106. end;
  107.  
  108. procedure TMyThread.WakeUp;
  109. begin
  110.   RTLeventSetEvent(FSleepEvent);
  111. end;
  112.  
  113. constructor TMyThread.Create(CreateSuspended: Boolean; const StackSize: SizeUInt);
  114. begin
  115.   Inherited Create(True);
  116.   FSleepEvent:= RTLEventCreate;
  117. end;
  118.  
  119.  
  120. { TForm1 }
  121.  
  122. procedure TForm1.btnMonitorClick(Sender: TObject);
  123. begin
  124.   if btnMonitor.Caption='Start Monitoring' then
  125.   begin
  126.     if Trim(FileToCheck.FileName) = '' then
  127.     begin
  128.       ShowMessage('Please select a file to monitor!');
  129.       btnMonitorClick(nil);  //Pauses the timer and updates the button
  130.       Exit;
  131.     end;
  132.  
  133.     if not FileExists(FileToCheck.FileName) then
  134.     begin
  135.       ShowMessage(FileToCheck.FileName +' does not exist');
  136.       btnMonitorClick(nil);  //Pauses the timer and updates the button
  137.       Exit;
  138.     end;
  139.  
  140.     btnMonitor.Enabled:=False;
  141.     btnMonitor.Caption:='Stop Monitoring';
  142.     spinInterval.Enabled:= not spinInterval.Enabled;
  143.     FileToCheck.Enabled:= not FileToCheck.Enabled;
  144.  
  145.     Thread:= TMyThread.Create(True);
  146.     Thread.MonitorInterval:=spinInterval.Value * 1000;
  147.     Thread.SetFileAge(FileAge(FileToCheck.FileName));
  148.     Thread.FreeOnTerminate:=True;
  149.     Thread.Start;
  150.  
  151.     btnMonitor.Enabled:=True;
  152.     btnMonitor.Font.Color:=clRed;
  153.   end
  154.   else
  155.   begin
  156.     btnMonitor.Enabled:=False;
  157.     btnMonitor.Caption:='Start Monitoring';
  158.  
  159.     Thread.Terminate;  //Signal thread to finish
  160.     Thread.WakeUp;     //Sets the FSleepEvent, thread wakes up, finds that
  161.                        //it is terminated and self destructs
  162.     Thread.WaitFor; //Wait for thread to finish
  163.  
  164.     btnMonitor.Enabled:=True;
  165.     spinInterval.Enabled:= not spinInterval.Enabled;
  166.     FileToCheck.Enabled:= not FileToCheck.Enabled;
  167.     btnMonitor.Font.Color:=clGreen;
  168.   end;
  169. end;
  170.  
  171. procedure TForm1.FormCreate(Sender: TObject);
  172. begin
  173.   FileToCheck.FileName:= Application.Location + 'data.dat';
  174. end;
  175.  
  176. procedure TForm1.LogMessage(AValue: string);
  177. begin
  178.   { Callback, called from thread }
  179.   lbLog.Items.Add(AValue);
  180.   lbLog.ItemIndex:=lbLog.Count -1;
  181. end;
  182.  
  183. end.

@Marcov I agree completely about the code in the youtube clip. But aside of the shortcomings it shows how to call synchronize and update the main form. Just that it does it too much. :-)
« Last Edit: June 24, 2017, 02:57:57 am by kapibara »
Lazarus trunk / fpc 3.2.2 / Kubuntu 22.04 - 64 bit

anderbelluno

  • New Member
  • *
  • Posts: 39
Re: thread
« Reply #8 on: June 24, 2017, 09:17:19 am »
O banco é Firebird,
Obrigado pela dica, tenho alguns programas feitos em Delphi2010 e estou migrando para o Lazarus, por isso, que estou com dificuldades.
Obrigado Amigo.

 

TinyPortal © 2005-2018