AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

var-Parameter mit Thread nutzen

Ein Thema von Viktorii · begonnen am 12. Feb 2008 · letzter Beitrag vom 21. Feb 2008
Antwort Antwort
Seite 1 von 3  1 23      
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#1

var-Parameter mit Thread nutzen

  Alt 12. Feb 2008, 15:05
Hallo.
In einem Thread wird eine Funktion (USBAsyncRead) aufgerufen, welche als Argument einen var-Parameter benötigt. In diesen var-Parameter werden die Daten geschrieben, welche von dieser Funktion generiert werden.
Nun suche ich einen Weg diese Daten nach Beendigung des Threads, außerhalb des Threads weiterverwenden zu können. Daher habe ich versucht meinem Thread einen var-Parameter (tData) zu übergeben, welchen ich dann an die oben erwähnte Funktion weitergebe.

Das sieht so aus:
Delphi-Quellcode:
type
  TBulkCommandThread = class(TThread)
  private
    ...
    ...
    Data : TDataFrame;
    ...
    ...
  protected

  public

  end;


  TBulkReceiveCommandThread = class(TBulkCommandThread)
  private
    ...
    ....
  protected
    procedure Execute; override;
  public
    constructor create(tPipeHandle : USB_PIPE_HANDLE;
                       var tData : TDataFrame;
                       tDSPMessage : Pointer;
                       tStatus : Pointer);
  end;



constructor TBulkReceiveCommandThread.create(tPipeHandle : USB_PIPE_HANDLE;
                                             var tData : TDataFrame;
                                             tDSPMessage : Pointer;
                                             tStatus : Pointer);
begin
    PipeHandle := tPipeHandle;
    Data := tData;
    DSPMessage := tDSPMessage;
    Status := tStatus;
    inherited create(False);
end;





procedure TBulkReceiveCommandThread.Execute();
begin
  ...
  ...

  // receive Data
  bRet := USBReadAsync(PipeHandle,      
                       Data,
                       USBcb.nDATA,
                       FenumProcInst);
  ...
  ...
end;
Die Daten liegen nun in Data, sind aber außerhalb des Threads nicht verfügbar. Erscheint mir auch logisch, weil Data wohl nicht mehr das Selbe ist wie der wirkliche var-Parameter tData.
Wie kann ich mein Problem lösen?

Habe auch schon einen Lösungsansatz mit Zeigern probiert, aber ein Problem ist schon mal, dass USBAsyncRead einen var-Parameter und keinen Zeiger benötig. Ich weiß zwar, dass ein var-Parameter intern als Zeiger behandelt wird, aber wenn ich einen Zeiger übergebe, ändert sich auf einmal der Inhalt des Zeigers und nicht die Speicherstelle auf der er zeigt. Scheint mir also auch nicht der richtige Ansatz zu sein.

Habe auch mit Hilfe der SuFu keine Lösung finden können.

Wer weiß Rat?
Vielen Dank.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: var-Parameter mit Thread nutzen

  Alt 12. Feb 2008, 15:10
Da musst du wohl besser direkt einen Zeiger übergeben, denn derzeit wird in deinem Constructor TDataFrame kopiert.

Delphi-Quellcode:
type PDataFrame=^TDataframe;


constructor xyzThread.create(...; Data:PDataFrame);
//und jetzt immer mit PDataFrame arbeiten


//aufrufen kannst du den constructor dann so
xyzThread.create(... @Data);
//..wenn Data eine Variable vom Typ TDataFrame im HauptThread ist.
Achte dabei auch auf die Synchronisierung!
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#3

Re: var-Parameter mit Thread nutzen

  Alt 13. Feb 2008, 08:39
Hallo sirius. Vielen Dank für Deine Antwort.

Zitat von sirius:
Da musst du wohl besser direkt einen Zeiger übergeben, denn derzeit wird in deinem Constructor TDataFrame kopiert.

Delphi-Quellcode:
type PDataFrame=^TDataframe;


constructor xyzThread.create(...; Data:PDataFrame);
//und jetzt immer mit PDataFrame arbeiten


//aufrufen kannst du den constructor dann so
xyzThread.create(... @Data);
//..wenn Data eine Variable vom Typ TDataFrame im HauptThread ist.
Ich verstehe das leider noch nicht so ganz. Okay, wenn ich es so mache, habe ich den Zeiger im Constructor. Wie komme ich in meiner Execute Prozedur an den Zeiger?

Das ist ja das Problem was ich bis jetzt auch hatte: Der var-Parameter stand mir im Constructor zur Verfügung. Ich wußte nicht wie ich in der Execute Prozedur an ihn rankomme. Also hab ich ihn in ein Feld kopiert. Allerdings macht dies natürlich die Funktionsweise des var-Parameters zu nichte...

Wie ich im ersten Post schon erwähnt hatte, braucht meine Funktion im Thread eigentlich einen var-Parameter und keinen Zeiger. Wenn ich ihr einen Zeiger übergebe, ändert sich der Inhalt des Zeigers, also die in ihm enthaltene Adresse und nicht die Speicherstelle auf der er zeigt.
Gibt es eine Möglichkeit einer Funktion, welche einen var-Parameter benötigt einen Zeiger zu übergeben?


Zitat von sirius:
Achte dabei auch auf die Synchronisierung!
Werde ich drauf achten.

Vielen Dank
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: var-Parameter mit Thread nutzen

  Alt 13. Feb 2008, 09:02
(Ich nehme an das TDataframe ein Record ist)

Ich versuchs mal an deinem Beispiel (geänderte Zeilen sind kommentiert)
Delphi-Quellcode:
type PDataframe=^TDataFrame; //hinzugefügt

type
  TBulkCommandThread = class(TThread)
  private
    ...
    ...
    Data : PDataFrame; //geändert
    ...
    ...
  protected

  public

  end;


  TBulkReceiveCommandThread = class(TBulkCommandThread)
  private
    ...
    ....
  protected
    procedure Execute; override;
  public
    constructor create(tPipeHandle : USB_PIPE_HANDLE;
                       tData : PDataFrame; //geändert
                       tDSPMessage : Pointer;
                       tStatus : Pointer);
  end;



constructor TBulkReceiveCommandThread.create(tPipeHandle : USB_PIPE_HANDLE;
                                             tData : PDataFrame; //geändert
                                             tDSPMessage : Pointer;
                                             tStatus : Pointer);
begin
    PipeHandle := tPipeHandle;
    Data := tData;
    DSPMessage := tDSPMessage;
    Status := tStatus;
    inherited create(False);
end;





procedure TBulkReceiveCommandThread.Execute();
//hier würde ich zum synchronisieren den Inhalt von TDataframe kurz zwischensepichern
//var tempData=TDataFrame;
begin
  ...
  ...

  // receive Data
  tempData:=Data^; //ich weiß nicht, ob du Data vorbelegen musst (evtl. synchronisieren)
  bRet := USBReadAsync(PipeHandle,      
                       tempData,
                       USBcb.nDATA,
                       FenumProcInst);
  
  Data^:=tempData; //Diese Zeile muss synchronisiert werden
  ...
  ...
end;
Aufrufen kannst du den Constructor so:
Delphi-Quellcode:
//es existiert in der Klasse, die den Thread aufruft eine Variable DataFrame vom Typ TDataFrame;
BulkReceiveCommandThread:=TBulkReceiveCommandThread.create(tPipeHandle,
                                                           @DataFrame,
                                                           tDSPMessage,
                                                           tStatus);
Du übergibst jetzt mit PDataframe nicht den Record sondern einen Zeiger auf den Record. Der Record selbst existiert jetzt nur einmal im MainThread.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#5

Re: var-Parameter mit Thread nutzen

  Alt 13. Feb 2008, 10:46
Jetzt ist mir klar geworden wie das funktioniert und bin schon mal ein ganzes Stück schlauer. Vielen Dank.

Über die Notwendigkeit des Synchornisierens und auch über den Grund dafür bin ich mir bewusst. Allerdings habe ich so etwas bis jetzt noch nie gemacht und weiß nicht wirklich wie man das macht. Macht man es in diesem Fall auch mit der TThread.Synchronize Methode?


Zitat von sirius:
Delphi-Quellcode:
procedure TBulkReceiveCommandThread.Execute();
//hier würde ich zum synchronisieren den Inhalt von TDataframe kurz zwischensepichern
//var tempData=TDataFrame;
begin
  ...
  ...

  // receive Data
  tempData:=Data^; //ich weiß nicht, ob du Data vorbelegen musst (evtl. synchronisieren)
  bRet := USBReadAsync(PipeHandle,      
                       tempData,
                       USBcb.nDATA,
                       FenumProcInst);
  
  Data^:=tempData; //Diese Zeile muss synchronisiert werden
  ...
  ...
end;

Wie genau kann ich dies Zeile synchronisieren? Mir ist schon klar, dass tempData erst dann nach Data^ zugewiesen werden darf, wenn USBReadAsync das Schreiben in tempData beendet hat. Aber wie ist da der richtige Ansatz?
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: var-Parameter mit Thread nutzen

  Alt 13. Feb 2008, 11:02
Was macht die Funktion "USBReadAsync"? Ist das ein weiterer Thread. Oder ist die Funktion blockierend?
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#7

Re: var-Parameter mit Thread nutzen

  Alt 13. Feb 2008, 11:28
Zitat von sirius:
Was macht die Funktion "USBReadAsync"? Ist das ein weiterer Thread. Oder ist die Funktion blockierend?
Die Funktion blockiert nicht sondern kehrt sofort zurück und läuft so 'parallel' um so asynchrone Kommunikation zu ermöglichen. Muss dann eigentlich ein weiteren Thread aufmachen, denke ich... Ist eine Funktion die ich aus ner dll bekomme, kann also nicht nachschauen, was sie wirklich macht....
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: var-Parameter mit Thread nutzen

  Alt 13. Feb 2008, 11:51
Dann machst du also einen Thread für einen Thread?
Ich sehe grad nicht durch um dir sinnvoll weiterzuhelfen.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#9

Re: var-Parameter mit Thread nutzen

  Alt 13. Feb 2008, 12:17
Zitat von sirius:
Dann machst du also einen Thread für einen Thread?
Ich sehe grad nicht durch um dir sinnvoll weiterzuhelfen.
Ja, weil die Funktion USBReadAsync zwei mal im Thread aufgerufen wird. Das zweite mal darf sie aber erst aufgerufen werden, wenn die erste beendet ist. Das kann ich mit WaitForSingleObject und Events, welche ich in den Callbackfunktionen der USBReadAsync Fkt. setze, kontrollieren.
Wenn nun aber die erste USBReadAsync Fkt. etwas länger braucht, wäre meine Anwendung für diese Zeit blockiert. Um dies zu umgehen, habe ich mir gedacht, ich lasse die beiden Funktionen in einem separaten Thread laufen.


Oder wäre es schon vernünftig synchronisiert, wenn ich die Zuweisung erst dann Vornehme, sobald das Event in der jeweiligen Callback Funktion (also USBReadAsync ist somit beendet) gesetzt worden ist?
Jetzt wo ich darüber nachdenke... ist doch bestimmt das damit gemeint, oder?
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: var-Parameter mit Thread nutzen

  Alt 13. Feb 2008, 13:38
Ja, ich denke wir meinen dasselbe.

Du hast aber 2 Synchronisationsmomente. Einmal die Übergabe von DataFrame von dem USB-Thread auf deinen Thread (das machst du in der CallBackMethode oder nach dem Waitforxxxobject). Und dann nochmal von deinem Thread an den MainThread. Und da das in dem Fall dieselbe Zuweisung ist müsstest du 3 Thread gleichzeitig synchronisieren. Am einfachsten wäre es wahrscheinlich, das ganze in synchronize (-Methode) auszulagern.
Man könnte auch selber mit Messages arbeiten (oder Critical Sections). Was hier günstiger ist, kann ich so nicht sagen.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz