NoCee hat geschrieben:Mit einem "zusätzlichen Thread" hab ich da gleich ein Problem, da ich grade mal wage weiß was das überhaupt darstellt.
Ein Thread ist so was ähnliches wie ein zusätzliches gleichzeitig laufendes Programm. Ein Programm besteht also aus mindestens einem Thread (dem sogenannten Mainthread) und beliebig vielen weiteren ("Worker") - Threads. Im Gegensatz zu eigenständigen Programmen verwenden alle Threads eines Programms denselben Speicher und dieselben offenen Dateien. (Das ist die Kurzfassung, es gibt da noch viel zu zu sagen und man kann auch unterschiedliche Arten von Threads erzeugen, das ist hier aber nicht relevant.)
In Lazarus gilt darüber hinaus:
- solange man nichts weiteres tut läuft der "Mainthread"
- Threads erzeugt man am besten als Instanz eines von TThread abgeleiteten Objektes
- nur der Mainthread kann "Event-Orientiert" programmiert werden (der User-Code steht ausschließlich in vom System erzeugte Events (OnClick, OnTimer, ... ), Threads dagegen laufen nur im "Execute" des Objektes. (TTimer geht also im Thread nicht !!!)
- nur im Mainthread darf auf GUI-Funktionalitäten (dazu gehört auch TTimer, leider ist nirgendwo sauber dokumentiert was als GUI-Funktionalität zu gelten hat) der FCL zugegriffen werden (tut man das in einem Thread stürzt das Programm ab !!!!))
- Ein Thread muss entweder so programmiert werden, dass er eine Aktion ausführt und sich dann beendet (aus Execute herausläuft), oder - wenn er als Dauerläufer in einer "Endlos"-Schleife arbeiten soll, er immer wieder auf eine Aktion kommt, die im Betriebssystem wartet (z.B. In Deinem Projekt im "blocking" Modus auf Zeichen aus der seriellen Schnittstelle wartet). Zur Not kann auch "sleep" helfen.
- mit "TThread.Synchronize" und "Application.QueuAsyncCall" (und den Windows-infizierten "Message"-Methoden) kann ein Thread ein Mainthread-Event auslösen, um z.B. GUI-Aktionen vom Mainthread ausführten zu lassen.
- Wenn man Speicher-Bereiche (Variablen) gemeinsam mit mehreren Thread (auch Mainthread) verwendet (z.B. zur Daten-Übergabe und Synchronisation), miss man diese gegen konkurrierende Zugriffe schützen. Man kann hier (z.B.) (für einzelne Zahlen) "Atomic" Funktionen verwenden (sehr schnell) oder (normal) mit vorgegebenen Objekten arbeiten (TThreadList) oder eigene Schutz-Mechanismen mit "TCriticalSection" einbauen.
In jedem Fall muss man beim Programmieren von Threads ziemlich aufpassen, damit man nichts falsch macht. (Beispiel: TList und TStringlist gelten als nicht Threadfest. Eine Instanz von TList oder TStringlist darf nicht von mehreren Thread verwendet werden, mehrere Threads dürfen allerdings durchaus jeweils unterschiedliche Instanzen von TList und TStringlist verwenden. Strings sind (soweit ich weiß) Threadfest implementiert, so dass mehrere Threads dieselben Strings verwenden können. ThreadList ist (natürlich) definitionsgemäß Threadfest.
Zu Deinem Problem:
Daten-Empfang von asynchronen Schnittstellen kann man eigentlich nur sinnvoll in einem Thread (mit Blocking Read) machen. (Dasselbe gilt für alle anderen Datenströme wie TCP/IP-Sockes, Pipes, ...)
Deshalb gibt es für Delphi mit "AsyncPro" ein (inzwischen kostenloses) Tool (nur für Windows), mit dem man beliebig viele Schnittstellen (Asynchron und TCP/IP), aufmachen kann und das die komplexe Thread-Technik im inneren versteckt. An das User-Programm werden Daten mittles Main-Thread-Events übergeben. So braucht der Anwender-Programmierung sich um die Threads überhaupt nicht kümmern.
Leider hat sich noch niemand die Mühe gemacht den (auf Sourceforge frei verfügbaren) Code nach Lazarus und Linux zu portieren

. Soweit ich weiß gibt es auch nichts vergleichbares (zumindest kommt der Wunsch danach regelmäßig in diversen Lazarus-Foren immer wieder auf).
Hope this helps,
-Michael