GetClipboardText() im Thread fuehrt zu Crash

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Programie
Beiträge: 1280
Registriert: 06.08.2005 22:56
Computerausstattung: https://www.sysprofile.de/id160800
Wohnort: Gernsbach
Kontaktdaten:

GetClipboardText() im Thread fuehrt zu Crash

Beitrag von Programie »

Ich habe ein sehr merkwuerdiges Problem: Wenn ich GetClipboardText() in einem mit CreateThread() gestarteten Thread aufrufe crasht sehr oft die Anwendung. Im Fehlerfall steht in der Debug Ausgabe fuer Zeile 11 (die Zeile mit "WaitWindowEvent()") "Program aborted. (by external library)".

Beispiel:

Code: Alles auswählen

Procedure Test(param)
  Repeat
    Debug GetClipboardText()
    Delay(1000)
  ForEver
EndProcedure

OpenWindow(0, 0, 0, 100, 100, "Test", #PB_Window_ScreenCentered)
CreateThread(@Test(), 0)

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Ich weiss nicht, ob das nur bei mir so ist, an der Linux version von PB liegt oder eventuell sogar ein Bug in PB ist.

Das Problem tritt sowohl bei einem Thread Safe Executable als auch bei einem Executable ohne Thread Safe auf.

PB: 5.62 (x64) + 5.70 LTS beta 3 (x64)
OS: Ubuntu 18.10 (Gnome 3)

Ich habe hier im Forum schon Code gesehen, wo auch GetClipboardText() in einem Thread verwendet wurde, daher gehe ich mal davon aus, dass das normalerweise funktionieren sollte.
BildBildBildBild
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: GetClipboardText() im Thread fuehrt zu Crash

Beitrag von ccode_new »

GetClipboardText() ist nicht Thread Safe.

Aber schaue dir das hier mal an:

viewtopic.php?f=8&t=29728
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
Programie
Beiträge: 1280
Registriert: 06.08.2005 22:56
Computerausstattung: https://www.sysprofile.de/id160800
Wohnort: Gernsbach
Kontaktdaten:

Re: GetClipboardText() im Thread fuehrt zu Crash

Beitrag von Programie »

Bedeutet also, man sollte die Clipboard Funktionen nur in der Main Loop aufrufen und aus dem Thread nur ein Signal an die Main Loop schicken, dass man die Funktion aufrufen moechte. Und anschliessend eben auf das Ergebnis abwarten (bei einem GetClipboardText() Aufruf).

Danke, das hilft mir schonmal weiter. Werde ich mal testen. :allright:

Gibt es alternativ dazu noch irgendwelche Linux API Clipboard Funktionen welche in einem Thread funktionieren? Ich kann mir nicht vorstellen, dass das grundsaetzlich nur in der Main Loop funktioniert.
BildBildBildBild
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: GetClipboardText() im Thread fuehrt zu Crash

Beitrag von ccode_new »

Hallo Programie,

unter Linux ist das Thema viel komplexer und komplizierter als unter Windows.

Ich frage mich ob PureBasic die Funktionen aus der xlib nutzt oder die thread-stabileren Funktionen aus der moderneren XCB-Lib.

Auch gtk oder qt haben intern Clipboard-Funktionen.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
Programie
Beiträge: 1280
Registriert: 06.08.2005 22:56
Computerausstattung: https://www.sysprofile.de/id160800
Wohnort: Gernsbach
Kontaktdaten:

Re: GetClipboardText() im Thread fuehrt zu Crash

Beitrag von Programie »

OK, konnte das Problem jetzt mit einem Custom Event mit PostEvent() und BindEvent() loesen. Danke fuer den indirekten Tipp durch den verlinkten Thread!

In meinem Thread rufe ich einfach PostEvent() auf wenn etwas gemacht werden soll und in dem Callback, welches ich an BindEvent() uebergebe, werden dann die Clipboard Funktionen aufgerufen. Solange man da keine zeitintensiven Aufgaben ausfuehrt funktioniert das auch problemlos (was in meinem Fall kein Problem ist). Ich muss in meinem Fall den Thread nur verwenden, da ich da mit ReadData() auf Daten von einem Linux Input Device (/dev/input) warte und sonst die Main Loop blockieren wuerde.
BildBildBildBild
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: GetClipboardText() im Thread fuehrt zu Crash

Beitrag von DarkSoul »

@ccode_new:
Lasse den Code mal mit eingeschalteter Konsole abstürzen. Dann kannst du es an der Konsolenausgabe sehen:

Code: Alles auswählen

[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
purebasic_compilation0.out: ../../src/xcb_io.c:259: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
:)

Da ist natürlich ein "Tipp" vergraben: Wenn du Threadsafe in den Compilereinstellungen einschaltest, dann funktioniert der Code einwandfrei.
Bild
Benutzeravatar
Programie
Beiträge: 1280
Registriert: 06.08.2005 22:56
Computerausstattung: https://www.sysprofile.de/id160800
Wohnort: Gernsbach
Kontaktdaten:

Re: GetClipboardText() im Thread fuehrt zu Crash

Beitrag von Programie »

DarkSoul hat geschrieben:Wenn du Threadsafe in den Compilereinstellungen einschaltest, dann funktioniert der Code einwandfrei.
Wie in meinem ersten Post genannt funktionierte bei mir das weder mit Threadsafe als auch ohne Threadsafe.
BildBildBildBild
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: GetClipboardText() im Thread fuehrt zu Crash

Beitrag von DarkSoul »

Ich habe Ubuntu 18.04. Vielleicht verhält sich 18.10 anders.

Hast du es denn mal bei eingeschalteter Konsole abstürzen lassen? Erhältst du eine andere Meldung?
Bild
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: GetClipboardText() im Thread fuehrt zu Crash

Beitrag von ccode_new »

Code: Alles auswählen

;Linux-Clipboard-Test

;Wer warten kann ist klar im Vorteil!!!

;Synchronisation ist Alles ;)

;Vieles ist ein meist unbemerkter Thread.
;(Zum Beispiel eine MsgBox ausgeben, einen Sound abspielen, etc.)

;Ich glaube die Clipboard-Befehle sind eigene Threads. Liege ich da richtig ?

DisableDebugger ;Der böse Debugger muss aus.

Global pThread1, pThread2, gesendet.b = #False, gelesen.b = #False

Macro GetClipboard()
  PrintN(GetClipboardText())
EndMacro

Macro SetClipboard(text)
  SetClipboardText(text)
EndMacro

Procedure ShowClipboardText(Parameter)
  gelesen = #False
  GetClipboard()
  ClearClipboard()
  gelesen = #True
EndProcedure

Procedure UseClipboardText(cliptext)
  gesendet = #False
  SetClipboard(PeekS(cliptext, -1))
  gesendet = #True
EndProcedure

;Mein fragwürdiges Programm

OpenConsole("Thread-Test!")
ClearClipboard()
pThread1 = CreateThread(@UseClipboardText(), @"Hallo Thread")
WaitThread(pThread1)
If gesendet = #True
  pThread2 = CreateThread(@ShowClipboardText(), 0)
EndIf
WaitThread(pThread2)
If gelesen = #True
  pThread1 = CreateThread(@UseClipboardText(), @"Neue Nachricht")
  WaitThread(pThread1)
  If gesendet = #True
    pThread2 = CreateThread(@ShowClipboardText(), 0)
  EndIf
EndIf
Input()
CloseConsole()
End
Funktioniert mit 1000 Ausrufe- und Fragezeichen. ;)
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: GetClipboardText() im Thread fuehrt zu Crash

Beitrag von mk-soft »

Clipboard funktionen im Thread aufrufen geht nicht sicher.

Das Beispiel ruft ja immer noch die Funktionen im Thread auf...
Werde mal ein Einfaches Bespiel mit Thread schreiben, obwohl das Modul ThreadToGUI dieses bereit macht.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Antworten