Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

Lazarus thread hatasi

Başlatan z, 31 Temmuz 2020, 15:05:24

z

Asagidaki thread uygulamasi Delphide calisiyor fakat Lazarusta Buton1'e basildiginda uygulama kapandi diye sistem mesaji cikiyor.


Sorun nedir?

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type

  TMsgRecord = record
    Cmd    : Integer;
    msg    : string[30];
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  id1: LongWord;
  thread1 : Integer;
  msg1 : TMsgRecord;
  Flag: Boolean;

Implementation
{$R *.dfm}        // Include form definitions

ThreadVar         // We must allow each thread its own instances
msgPtr : ^TMsgRecord;

// Private thread procedure to show a string


function BenimThread(Parameter : Pointer):boolean;
var i:integer;
begin
        i:=0;
        msgPtr := Parameter;
        form1.Label1.Caption:='Thread Basladi: '+IntToStr(msgPtr.Cmd);
        while Flag do i:=i+1;
        CloseHandle(thread1);
        form1.Label2.Caption:='Thread Bitti i='+inttostr(i);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
        msg1.Cmd := $FFFF;
        msg1.msg    := 'Hello World';

        Flag:=true;
        thread1 := BeginThread(nil, 0, Addr(BenimThread), Addr(msg1), 0, id1);
end;

procedure TForm1.Button2Click(Sender: TObject);
var i:integer;
begin
        Flag:=false;
end;

end.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

ercan_t


treadler temel olarak böyle kullanılmaz criticalsection kullanman lazım.

Eğer thread içinde bir değişkeni thread dışında kullanırsan access violation at address hatasını alırsın.(genel olarak)
thread konusunda değikeni değiştirirken thread lock ve unlock konularını incelemeni tavsiye ederim.





z

Bu sekilde herseyi degiskenleri devre disi biraksam da program duruyor.

function BenimThread(a:integer):boolean;
var i:integer;
begin
        //i:=0;
        //msgPtr := Parameter;
        //form1.Label1.Caption:='Thread Basladi: '+IntToStr(msgPtr.Cmd);
        //while Flag do i:=i+1;
        FileClose(thread1);
        //form1.Label2.Caption:='Thread Bitti i='+inttostr(i);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
        msg1.Cmd := $FFFF;
        Flag:=true;
        thread1 := BeginThread(nil, 0, Addr(BenimThread), Addr(msg1), 0, id1);
end;   
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

ercan_t

bak orada yine tread1 kullanmışsın oda genel bir değişken

FileClose(thread1); yerine EndThread(0);

kullanmalısın.

z

Delphide veri hazir/hazir degil anlaminda sadece bir tane byte tipi flag kullanarak ana programdan bufferi doldurup thread tarafinda bufferi okuyarak sorunsuz pek cok program yazdim.

Hic sorun yasamadim.

Daha baska bir sorun var.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

power20

#5
Flag, Buffer vb. yazma silme esnasında çakışma olmaması için waitforsingleobject doğru şekilde kullanılmalıdır. Sadece kullanmak yetmez.

Bir bilgisayarda sorunsuz, diğerinde az sorunlu, öbüründe tam sorunlu olabilir. Yapılan işlerin zamanlarının denk gelmesiyle sorun çözülmüş gibi avunulabilir. Sorun 6 saat sonra çıkabilir

z

1 byte lik alan isgal eden flag kullanilmasi durumunda nasil bir cakisma olabilir?

Bir senaryo yazabilirmisin?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Alıntı yapılan: ercan_t - 02 Ağustos 2020, 21:42:09bak orada yine tread1 kullanmışsın oda genel bir değişken

FileClose(thread1); yerine EndThread(0);

kullanmalısın.

Ne alaka?

Thread1 denilen handler degeri ramda duran ve olusturlduktan sonra hic kimsenin icerigiyle oynamadigi bir degisken.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com