ich hab ein komisches Problem bei dem ich nicht weiter weiß. Ich hab eine normale Anwendung die einige rechenintensive Routinen in extra Threads auslagert. Auf Windows fgunctionniert alles ohne Probleme doch unter Linux (64bit) schmiert die Anwendung ohne Fehler ab. Wenn ich ddas Programm in der Console starte bekomm ich folgende Meldung:
[xcb] Unknown sequence number while processing reply [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called [xcb] Aborting, sorry about that.
Ich hab dazu auch schon ein paar Topics bei google gefunden, aber keins von denen hatte ne Lösung parat. Die einen sagen ich muss XInitThread aus der xlib aufrufen, doch wenn ich das mach schmieren mir die Ciritical Sections aus der pthread-Unit weg. Andere sagen ich muss einfach die cthread-Unit in die uses aufnehmen, doch die ist schon drin und wird auch genutzt. Wo also soll ich noch nach einer Lösung suchen? Hat von euch jmd ne Ahnung was ich gegen das Problem machen kann, oder ist das evtl. ein Bug im Lazarus?
Bergmann89 hat geschrieben:Die einen sagen ich muss XInitThread aus der xlib aufrufen, doch wenn ich das mach schmieren mir die Ciritical Sections aus der pthread-Unit weg.
An welcher Stelle hattest du denn den Aufruf platziert? Nach meinem Verständnis müsste sie in einem Initialization-Abschnitt einer Unit, die nach cthreads aber vor Interfaces im Programm eingebunden wird, aufgerufen werden -- indirekte Abhängigkeiten wären dabei zu berücksichtigen.
MfG Socke Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Wenn man xlib aus threads aufrufen will, braucht es einige Vorkehrungen. Nach meiner Erfahrung reicht XInitThreads() nicht immer aus. In MSEgui benutze ich eine zentrale Aufrufstelle, welche durch Mutex geschützt ist und verzichte auf XInitThreads(). Falls du es trotzdem mit XInitThreads() versuchen möchtest, muss es, wie Socke schreibt, vor xopendisplay() (welches vermutlich in "Interfaces" steckt) aufgerufen werden. Hat das widgetset keine entsprechende Einstellung?
Ich habe gehört, dass es in Linux - genau wie in Windows - nicht möglich sei, dass eine Anwendung mehrere (X-) GUI-Sessions, jeweils in einem Thread, aufmacht (was ich ziemlich doof finde) und es deshalb nicht schlimm sein, dass die LCL nicht multithreading-fähig ist.
Einer meiner Anwender berichtet von dem gleichen Fehler (Bohdi Linux, Enlightment) im Netzwerkthread. Der Client arbeitet einwandfrei und verbindet sich mit einem entfernten Server. Aber wenn der Server lokal gestartet wird, kommt die gleiche Meldung wie bei dir sobald sich der (auch lokale) Client mit diesem Server verbindet (genau bei ServerSocket.CanRead()). Ich konnte den Fehler bei mir auf Arch Linux mit KDE nicht nachvollziehen, und auch in einer VB mit Bohdi lief alles problemlos. Ich rate, dass es an einer Bibliothek/einer bestimmten Kernelversion liegt. Eine Lösung habe ich aber nicht.
soweit ich weiß nutzte ich nix aus dem X System, zumindest nicht wissentlich. In den Threads lade und speichere ich Texturen. Die 2 Anwendungsfälle bei denen mir der Fehler aufgefallen ist sind folgende:
[Fall 1] - TJPEGImage erzeugen von HDD laden - TLatIntfImage erzeugen und aus Bitmap der JPEG laden: intf.LoadFromBitmap(jpeg.BitmapHandle, jpeg.MaskHandle) - IntfImage nutzen um die ByteDaten der JPEG in ein Format zu konvertieren, das die GrafikKarte lesen kann.
[Fall 2] - TexturDaten im BMP Format in einen MemoryStream speichern - normale TBitmap (die im MainThread erstellt wurde, aber zur Zeit von niemandem genutzt wird) aus dem MemoryStream laden
Ich hab auch nochmal ein wenig mit dem XInitThreads rumprobiert. Wenn ich ne extra Unit mach, die das XInitThreads im initialize hat und direct nach cthreads in den usings steht, dann gehts. Das scheint zwar ne Lösung zu sein, aber wirklich zufrieden bin ich damit auch nicht. Das muss doch auch iwie "sauber" gehen.
Meines Wissens darfst du keine TBitmap oder TJpegimage benutzen im separaten Thread. Das hängt alles an X, deshalb habe ich nachgefragt. Benutze die entsprechenden vom GUI losgelösten Varianten aus fpimage, FPReadJPEG etc..
hab mir das grad mal angesehen. TFPCustomImage hat zu wenig Informationen um damit weiter zu arbeiten. Ich brauch ne TLazIntfImage. Da die von TFPCustomImage erbt hab ich einfach die erstellt und geladen, aber die DataDescription wird trotzdem nicht richtig ausgefüllt. Gibts da ne Möglichkeit die TLazIntfImage zu laden?