Picproje Elektronik Sitesi

PROGRAMLAMA DİLLERİ => Delphi => Konuyu başlatan: z - 31 Temmuz 2020, 15:05:24

Başlık: Lazarus thread hatasi
Gönderen: z - 31 Temmuz 2020, 15:05:24
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.

Başlık: Ynt: Lazarus thread hatasi
Gönderen: ercan_t - 31 Temmuz 2020, 23:14:00

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.




Başlık: Ynt: Lazarus thread hatasi
Gönderen: z - 01 Ağustos 2020, 03:53:34
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;   
Başlık: Ynt: Lazarus thread hatasi
Gönderen: ercan_t - 02 Ağustos 2020, 21:42:09
bak orada yine tread1 kullanmışsın oda genel bir değişken

FileClose(thread1); yerine EndThread(0);

kullanmalısın.
Başlık: Ynt: Lazarus thread hatasi
Gönderen: z - 03 Ağustos 2020, 01:10:54
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.
Başlık: Ynt: Lazarus thread hatasi
Gönderen: power20 - 03 Ağustos 2020, 08:18:09
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
Başlık: Ynt: Lazarus thread hatasi
Gönderen: z - 03 Ağustos 2020, 10:14:30
1 byte lik alan isgal eden flag kullanilmasi durumunda nasil bir cakisma olabilir?

Bir senaryo yazabilirmisin?
Başlık: Ynt: Lazarus thread hatasi
Gönderen: z - 03 Ağustos 2020, 11:20:12
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.