|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
worldwidetrekking
Anmeldungsdatum: 22.08.2009 Beiträge: 38
|
Verfasst am: 16.05.2012, 22:23 Titel: Mutlithread GTK GUI hängt nach einigen Durchläufen |
|
|
Hallo,
ich hab gerade mal schnell eine kleine Test GUI gebastelt um einige GTK Funktionen zu testen, die ich in den nächsten Wochen in meinem aktuellen Projekt nutzen möchte. Die einzelnen Funktionen an sich machen auch was sie sollen - allerdings hängt sich das ganze nach einiger Zeit auf. Manchmal schon nach 6 oder 7 Durchläufen von Thread 1, manchmal auch erst nach 30 oder 40 Durchläufen.
Im PRinzip machen Thread 1 und 2 nichts anderes als ihre eigenen Durchläufe zu zählen, natürlich ist eine Wartezeit eingebaut.
Zusätzlich wird noch die aktuelle Systemzeit ermittelt und ausgegeben.
Kann mir irgendjemand weiterhelefen, wo mein Fehler liegen könnte? Ich hab langsam keine Idee mehr.
Da sich das ganze jedes mal zu einem anderen Zeitpunkt aufhängt tippe ich auf Speicherüberlauf - weiß aber nicht wieso...
Hier mal eine Grafik von der GUI:
Und hier der Code:
Code: | '* ---------------------------------------------------------------------------
'* Program shell generated by utility 'glade2bas'
'* provided by Klaus Siebke, http://www.siebke.com
'* Dieser Programmrahmen wurde generiert durch das Werkzeug 'glade2bas'
'*
'*
'* Generated at / Generierung am 11.05.2012 23:34
'* ---------------------------------------------------------------------------
'******************************************************************************
'* Program name: Test
'*
'* Version: x.x
'*
'* Author: xxx
'*
'* Description / Beschreibung:
'* --------------------------
'*
'* xxx
'*
'* License / Lizenz:
'* ----------------
'*
'* Please prefer the GNU GENERAL PUBLIC LICENSE to support free software
'* For more information please visit: http://www.fsf.org
'*
'* Bitte bevorzugen Sie die GNU GENERAL PUBLIC LICENSE und unterstuetzen
'* Sie mit Ihrem Programm die freie Software
'* Mehr Informationen finden Sie unter: http://www.fsf.org
'*
'*
'*
'******************************************************************************
'*
'* H I N T / H I N W E I S
'*
'* If the final application shall only show the GUI and not the command window,
'* compile the application with "fbc -s gui <progname>.bas"
'*
'* Wenn die fertige Anwendung nur im GUI-Modus laufen soll (ohne zusaetzliches
'* cmd-Fenster), einfach mit "fbc -s gui <programm>.bas" umwandeln
'*
'******************************************************************************
'* Include to be compatible with some VB commands / Ermoeglichen VB Befehle
'******************************************************************************
#include "vbcompat.bi"
'******************************************************************************
'* Includes for Gtk / Definitionen fuer Gtk
'******************************************************************************
#include "gtk/gtk.bi"
#include "gtk/libglade/glade-xml.bi"
#define NULL 0
#define FALSE 0
'#define TRUE <>0
#define G_THREADS_ENABLED
'******************************************************************************
'* Subroutines (callbacks) or 'events' in Visual Basic notation
'* Definition der Unterprogramme bzw. 'events' in Visual Basic notation
'******************************************************************************
'1) corresponding to the signals in the glade xml file / analog zu den Signalen
' in der glade xml Datei
#include "Test.decl"
'2) own routines / Eigene Routinen
''declare sub xxx()
Declare Function Timer1 CDECL (BYVAL user_data AS gpointer) AS gpointer
Declare Function Timer2 CDECL (BYVAL user_data AS gpointer) AS gpointer
Declare Function Zeit CDECL (BYVAL user_data AS gpointer) AS gpointer
Declare Function Zeitausgabe CDECL (BYVAL user_data AS gpointer) AS gpointer
'******************************************************************************
'* Data definitions / Datendefinitionen
'******************************************************************************
dim shared xml as GladeXML ptr
dim shared slash as string
dim shared window1 as GtkWidget ptr
dim shared Flag1 as Byte = 0
dim shared Flag2 as Byte = 0
dim shared Zaehler1 as Integer = 0
dim shared Zaehler2 as Integer = 0
dim shared i1 as Integer = 0
dim shared i11 as Integer = 0
dim shared i2 as Integer = 0
dim shared i22 as Integer = 0
dim shared z as Integer = 0
dim shared zz as Integer = 0
dim shared Systemzeit as String
dim shared label1 as GtkLabel ptr
dim shared label2 as GtkLabel ptr
dim shared label3 as GtkLabel ptr
dim shared label4 as GtkLabel ptr
dim shared G_Mutex as any ptr
dim Thread1 as GThread ptr
dim Thread2 as GThread ptr
dim Thread3 as GThread ptr
dim Thread4 as GThread ptr
'******************************************************************************
'*
'* =========================
'* START OF THE MAIN PROGRAM
'* BEGINN DES HAUPTPROGRAMMS
'* =========================
'*
'******************************************************************************
'******************************************************************************
'* Choose correct slash for the OS / Betriebssystemabhängiger Pfadbezeichner
'******************************************************************************
slash = "/"
#ifdef __FB_WIN32__
'...instructions only for Win32...
slash = "\"
#endif
'******************************************************************************
'* Initialize Gtk / GUI (Gtk) initialisieren
'******************************************************************************
gdk_threads_enter ()
gtk_init( NULL, NULL )
'******************************************************************************
'* Specify the windows to be shown / Anzuzeigende Fenster spezifizieren
'******************************************************************************
xml = glade_xml_new( "Test.glade", NULL, NULL )
'******************************************************************************
'* Reference some widgets / Fenster+Felder referenzieren
'******************************************************************************
window1 = glade_xml_get_widget( xml, "window1" )
label1 = glade_xml_get_widget( xml, "label1")
label2 = glade_xml_get_widget( xml, "label2")
label3 = glade_xml_get_widget( xml, "label3")
label4 = glade_xml_get_widget( xml, "label4")
'******************************************************************************
'* Display main window(s) / Hauptfenster anzeigen
'******************************************************************************
gtk_widget_show_all( window1)
glade_xml_signal_autoconnect( xml )
'******************************************************************************
'* The main GUI loop starts / Hier beginnt die eigentliche GUI-Verarbeitung
'* ------------------------------------------------------------------------
'*
'* I M P O R T A N T / W I C H T I G :
'*
'* gtk_main can only be terminated by function gtk_main_quit(), so remember to
'* define a signal to quit the application and call gtk_main_quit() in the
'* associated SUB - e.g. by signal on_xxx_delete_event (xxx = window name)
'*
'* gtk_main kann nur durch die Funktion gtk_main_quit() beendet werden, daher
'* nicht vergessen, ein Signal zum Beenden der Anwendung zu definieren und
'* in der zugehörigen SUB die Funktion gtk_main_quit() aufzurufen - z.B. durch
'* das Signal on_xxx_delete_event (xxx = Name des Fensters)
'*
'******************************************************************************
'******************************************************************************
'******************************************************************************
'* erstellen von Threads (vorher bereits definiert)
'******************************************************************************
Thread1 = g_thread_create_full(@Timer1, NULL, NULL, TRUE, NULL, G_THREAD_PRIORITY_NORMAL, NULL)
Thread2 = g_thread_create_full(@Timer2, NULL, NULL, TRUE, NULL, G_THREAD_PRIORITY_NORMAL, NULL)
Thread3 = g_thread_create_full(@Zeit, NULL, NULL, TRUE, NULL, G_THREAD_PRIORITY_NORMAL, NULL)
Thread4 = g_thread_create_full(@Zeitausgabe, NULL, NULL, TRUE, NULL, G_THREAD_PRIORITY_NORMAL, NULL)
'******************************************************************************
G_Mutex = Mutexcreate ()
gtk_main( )
'******************************************************************************
'* Wrap up / Abschliessende Schritte
'******************************************************************************
gdk_threads_leave
' a) unattach xml reference / xml Referenz abbauen
g_object_unref( xml )
' b) Finish program with return code 0 / Programm mit Returncode 0 beenden
end 0
'******************************************************************************
'*
'* =======================
'* END OF THE MAIN PROGRAM
'* ENDE DES HAUPTPROGRAMMS
'* =======================
'*
'******************************************************************************
'------------------------------------------------------------------------------
' now the SUB programs start ... / ab hier Unterprogramme (SUB's) ...
'------------------------------------------------------------------------------
FUNCTION on_window1_delete_event CDECL ALIAS "on_window1_delete_event" (BYVAL object AS GtkObject PTR, BYVAL event AS GdkEvent PTR, BYVAL user_data as gpointer) AS gboolean EXPORT
'******************************************************************************
'* put your code below for signal on_window1_delete_event
'******************************************************************************
gtk_main_quit()
Return NULL 'change appropriate / anpassen !!!
END FUNCTION
SUB on_button1_clicked CDECL ALIAS "on_button1_clicked" (BYVAL object AS GtkObject PTR, BYVAL user_data as gpointer) EXPORT
'******************************************************************************
'* put your code below for signal on_button1_clicked
'******************************************************************************
If Flag1 = 0 Then
gtk_label_set_text(label2, "Button 1 geklickt " &Zaehler1 &" mal")
Flag1 = 1
Zaehler1 = Zaehler1 + 1
Elseif Flag1 = 1 Then
gtk_label_set_text(label2, "Button 1 doppelt geklickt " &Zaehler1 &" mal")
Flag1 = 0
Zaehler1 = Zaehler1 + 1
End If
END SUB
SUB on_button2_clicked CDECL ALIAS "on_button2_clicked" (BYVAL object AS GtkObject PTR, BYVAL user_data as gpointer) EXPORT
'******************************************************************************
'* put your code below for signal on_button2_clicked
'******************************************************************************
If Flag2 = 0 Then
gtk_label_set_text(label2, "Button 2 geklickt")
Flag2 = 1
Elseif Flag2 = 1 Then
gtk_label_set_text(label2, "Button 2 doppelt gecklickt")
Flag2 = 0
End if
END SUB
'******************************************************************************
'* put your code below for own subroutines
'******************************************************************************
Function Timer1 CDECL (BYVAL user_data AS gpointer) AS gpointer
Do
For i1 = 0 to 10000
For i11 = 0 to 300
sleep 1
Next i11
gdk_threads_enter ()
gtk_label_set_text(label3, "Thread 1 Durchlauf Nr. : " &i1)
gdk_threads_leave ()
Next i1
Loop
return TRUE
End Function
Function Timer2 CDECL (BYVAL user_data AS gpointer) AS gpointer
Do
For i2 = 0 to 10000
For i22 = 0 to 600
sleep 1
Next i22
gdk_threads_enter ()
gtk_label_set_text(label4, "Tread 2 Durchlauf Nr. : " &i2)
gdk_threads_leave ()
Next i2
Loop
return TRUE
End Function
Function Zeit CDECL (BYVAL user_data AS gpointer) AS gpointer
Do
For z = 0 to 50
sleep 1
Next z
Mutexlock(G_Mutex)
Systemzeit = Time
Mutexunlock(G_Mutex)
Loop
return TRUE
End Function
Function Zeitausgabe CDECL (BYVAL user_data AS gpointer) AS gpointer
Do
For zz = 0 to 51
sleep 1
Next zz
Mutexlock(G_Mutex)
gdk_threads_enter ()
gtk_label_set_text(label1, "" &Systemzeit)
gdk_threads_leave ()
Mutexunlock(G_Mutex)
Loop
return TRUE
End Function
|
Viele Grüße w. |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 16.05.2012, 23:31 Titel: |
|
|
Ich vermute eher, dass dir irgendwas im Thread-Bereich in die Quere kommt. Vielleicht verwendest du irgendwo einen Zugriff, der nicht threadsicher ist (wie sieht das zum Beispiel mit der Erhöhung der Zähler aus?) _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
worldwidetrekking
Anmeldungsdatum: 22.08.2009 Beiträge: 38
|
Verfasst am: 19.05.2012, 01:09 Titel: |
|
|
Ich werds noch mal in Ruhe durchgehen und alles checken - wird aber erst am Pfingstwochenende was, weil ich kommende Woche Fachabiprüfungen hab...
Wenn ich den Fehler finde poste ich hier mal die Korrektur.
Danke für den Tipp!
Grüße w. |
|
Nach oben |
|
|
worldwidetrekking
Anmeldungsdatum: 22.08.2009 Beiträge: 38
|
Verfasst am: 23.05.2012, 12:08 Titel: |
|
|
Ich hab jetzt mal alle Threads entfernt und nur einen als SUB laufen lassen -> keine Probleme -> also liegt es irgendwo im Thread System.
Ich hatte Probleme mit dem g_thread_init
Habe dann irgendwo gelesen, dass das ab GTK Version 2.23 nicht mehr nötig sei und da ich Version 2.24 nutze hab ich das mal weggelassen. Beim Kompilieren gab das im gegensatz zu GTK 2.16 keine Fehlermeldung.
Also ging ich davon aus, dass es so ok wäre. Scheinbar ist aber trotzdem nicht alles Threadsafe...
Eigentlich muss ich ja die g_threads.lib linken. Vor einem guten Jahr hatte ich damit auch so meine lieben Probleme, habe es dann aber hinbekommen - damals mit GTK 2.16.
Jetzt will es beim besten willen nicht mehr. Es gibt immer ne Fehlermeldung von wegen: cannot find -lc:\...
Ich bekomms einfach nicht hin - hat da evtl. jemand nen Tipp für mich?
Viele Grüße
w. |
|
Nach oben |
|
|
worldwidetrekking
Anmeldungsdatum: 22.08.2009 Beiträge: 38
|
Verfasst am: 31.05.2012, 13:00 Titel: |
|
|
Stundenlanges probieren -> kein Ergebnis. Irgendwo is einfach der Wurm drinnen.
Die .lib is dafinitiv in dem Verzeichnis vorhanden.
Eventuell mache ich bei den Freebasic Einstellungen einen Fehler?!
So schaut es aus, wenn ich die gthread-2.0.lib zu linken versuche:
Und hier die Einstellungen:
Sieht da jemand wo der Fehler liegt? Habe ich den Befehl -l falsch eingesetzt?
Grüße w. |
|
Nach oben |
|
|
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 31.05.2012, 22:57 Titel: |
|
|
Normalerweise packt man Importbilbliotheken in den Linkersuchpfad und nutzt nur -l<name> ohne Dateierweiterung und lib-Präfix. Keine Ahnung, ob das überhaupt mit Pfadangaben geht. |
|
Nach oben |
|
|
worldwidetrekking
Anmeldungsdatum: 22.08.2009 Beiträge: 38
|
Verfasst am: 31.05.2012, 23:20 Titel: |
|
|
@28398: Wo sucht denn der Freebasic Linker normalerweise? Dann versuch ich das mal so wie du es schreibst...
Grüße w. |
|
Nach oben |
|
|
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 01.06.2012, 00:34 Titel: |
|
|
<FB root>/lib/win32 oder so. Da wo halt in der Freebasic-Distro die ganzen .a-Dateien liegen
Zusätzliche Linkersuchpfade müssten mit sowas wie -Wl,-L"Pfad" gehen. Keine Ahnung, wie stark FB da vom GCC abweicht, aber so in der Art sollte das gehen... |
|
Nach oben |
|
|
worldwidetrekking
Anmeldungsdatum: 22.08.2009 Beiträge: 38
|
Verfasst am: 01.06.2012, 14:53 Titel: |
|
|
Vielen Dank für deine Antwort - leider bekomm ich es immer noch nicht hin...
So schaut es bei mir momentan aus:
Hier mal der Link zu den Compilereinstellungen:
http://www.freebasic-portal.de/tutorials/compiler-optionen-30.html
Ich kann mich noch erinnern, dass ich das ganze vor fast 2 Jahren mal funktionsfähig hatte und das einfach nur mit der Optin -l ... ohne weitere Suchpfade für den Linker. Evtl. funktioniert das bei der aktuellen Freebasic bzw. FB Ide Version nicht mehr oder anderst.
Wenn es aber nicht in den nächsten Tagen funktioniert kann mich Freebasic mal gern haben - kann ja nicht sein, dass es nach Wochen voller Versuchen (auch an mehreren Rechnern) nicht funktioniert. |
|
Nach oben |
|
|
MOD Fleißiger Referenzredakteur
Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 01.06.2012, 15:28 Titel: |
|
|
Das Problem sitzt meist zwischen Stuhllehne und Tastatur.
Den Pfad musst du gar nicht angeben, wenn du alles in den lib-Ordner von FB kopiert hast. Neben diesem wird auch immer der Pfad durchsucht, in dem die .bas liegt, nur so zur Info.
Bei der Angabe der lib lässt man die Dateiendung für gewöhnlich weg, ein reines -l gthread-2.0 sollte reichen. Ich würde sowas normalerweise aber nicht per Hand machen. Eigentlich ist dafür die Header-Datei mit #INCLIB zuständig. |
|
Nach oben |
|
|
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 01.06.2012, 17:44 Titel: |
|
|
Die Importlib ist falsch benannt.
gthread-2.0.lib ist für den MSVC, in libgthread-2.0.a umbennen langt. Du gibts mit -l keine Dateinamen, sondern Bibliotheksnamen an. Es ist des Linkers Aufgabe die passende Datei zu finden. Zwischen -l und dem Namen kommt kein Leerzeichen. (Wird wohl vom Frontend automatisch korrigiert) |
|
Nach oben |
|
|
worldwidetrekking
Anmeldungsdatum: 22.08.2009 Beiträge: 38
|
Verfasst am: 04.06.2012, 21:35 Titel: |
|
|
Also irgendwie stimmt das ja:
Zitat: | Das Problem sitzt meist zwischen Stuhllehne und Tastatur. |
Ich habs jetzt zum Laufen bekommen - könnte aber schwören es genau so schon mal probiert zu haben. Aber das kann ja offensichtlich nicht sein, da es sonst schon mal funktioniert hätte...
Jetzt hängt sich meine GUI auch nicht mehr auf - ich kann es Stundenlang laufen lassen
Obwohl ich mir sicher war, dass ich bei meinem letzten GTK Multithreading Programm den kompletten Pfad eingegeben hab funktioniert es jetzt doch anderst:
Ich hab mir das jetzt mal als Screenshot gespeichert - aber nach dieser schweren Geburt werd ich vermutlich sowieso nicht mehr vergessen wie es richtig gemacht wird!
Vielen Dank für eure Hilfe!!! |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|