Multithreading / TCP/IP / Signal-Handling auf 64GB SMP Kernel (2.4) (SuSE Linux 8.2)
-
Es gibt globale Signal-Handler fuer die wichtigsten Signale.
Das Problem ist, dass die Fehler scheinbar nicht reproduzierbar sind. D.h. irgendein Thread kackt ab und reisst andere mit in den Tod. Ich werde heute das Ganze mal genauer angucken. Wie gesagt, das Problem tritt scheinbar nur bei echten Multiprozessor-Systemen auf, also koennte ich irgendwo eine Race-Condition haben, bei der 2 Threads gleichzeitig in einen Speicherbereich schreiben, die bei Uniprozessor-Systemen nicht auftritt.
Im Log habe ich gesehen, dass mehrere Threads mit SIGSEGV abbrechen, ich weiss bloss noch nicht welche (die Thread-IDs hab ich, aber das nuetzt mir nix). Ich werde mir das Ganze heute nochmal angucken. (Ich poste grade von zu Hause)
Ich schaetze mal, dass es irgendwo im Netzwerk-Code ist (eigene Library). Ich werde auch noch mal das Event- und Messaging-Subsystem pruefen.
-
Muss ein Problem deinen Programmes sein.
Ich habe hier eins mit 4 X Xeon und kein Probleme. Sei es nun mit den eigene Programmes oder MySQL,Apache u.s.w.
Kann aber sein das Suse da etwas gedreht hat. 8.2 ist ja nicht mehr die neueste.
-
Hat die Distro schon NPTL? Alles davor ist Mist.
-
Power Off schrieb:
Es gibt globale Signal-Handler fuer die wichtigsten Signale.
Das Problem ist, dass die Fehler scheinbar nicht reproduzierbar sind. D.h. irgendein Thread kackt ab und reisst andere mit in den Tod. Ich werde heute das Ganze mal genauer angucken. Wie gesagt, das Problem tritt scheinbar nur bei echten Multiprozessor-Systemen auf, also koennte ich irgendwo eine Race-Condition haben, bei der 2 Threads gleichzeitig in einen Speicherbereich schreiben, die bei Uniprozessor-Systemen nicht auftritt.
Im Log habe ich gesehen, dass mehrere Threads mit SIGSEGV abbrechen, ich weiss bloss noch nicht welche (die Thread-IDs hab ich, aber das nuetzt mir nix). Ich werde mir das Ganze heute nochmal angucken. (Ich poste grade von zu Hause)
Ich schaetze mal, dass es irgendwo im Netzwerk-Code ist (eigene Library). Ich werde auch noch mal das Event- und Messaging-Subsystem pruefen.
Meiner Meinung nach sollte man sich von dem ganzen Signal Zeug fernhalten. Man kann in einem Signalhandler eh nichts richtig sinnvolles machen. Valgrind hatte vor Version 2.4 das Tool helgrind, dass man zum Auffinden von Race Conditions benutzten konnte. Vielleicht hilft es dir.
-
Man "sollte" schon, aber meistens geht's halt dann doch nicht ganz. Nachdem das POSIX-API für Threads nicht gerade üppig ausgefallen ist, muss man leider fast immer mit den signals herumpfuschen.
-
Ringding schrieb:
Man "sollte" schon, aber meistens geht's halt dann doch nicht ganz. Nachdem das POSIX-API für Threads nicht gerade üppig ausgefallen ist, muss man leider fast immer mit den signals herumpfuschen.
Hast du Beispiele? Ich hab noch nie bei Threads einen Signalhandler gebraucht.
-
Naja, kommt drauf an, wie low level das sein soll. In unserer JVM an der Uni müssen wir z.B. alle Threads stoppen und unter bestimmten Bedingungen den program counter (EIP auf x86) umsetzen, sodass das Ding an einer anderen Stelle weiterläuft. Geht nicht ohne signals.
Es scheitert sogar schon am Stoppen aller Threads, IIRC.
-
Ringding schrieb:
Naja, kommt drauf an, wie low level das sein soll. In unserer JVM an der Uni müssen wir z.B. alle Threads stoppen und unter bestimmten Bedingungen den program counter (EIP auf x86) umsetzen, sodass das Ding an einer anderen Stelle weiterläuft. Geht nicht ohne signals.
Es scheitert sogar schon am Stoppen aller Threads, IIRC.
Naja, kein normales Programm sollte den Program Counter verändern wollen. Und das Stoppen aller Threads ist meistens ein Zeichen für schlechtes Design. Aber ich weiss nicht, wie das mit JVMs läuft. Wobei mir grad auch nicht einfällt, warum man das alles bei einer JVM machen möchte. Kommt wahrscheinlich auf die zu emulierende Sprache an (steht das J für Java?).
-
Ja klar, Java.
Schlechtes Design nicht, nur Fokussierung auf Performance, unter Ausnutzung aller Schweinereien ;). Der Boehm Garbage Collector, den wir auch verwenden, macht soundso schon von sich aus so ein signal-Zeugs, weil der auch irgendwie eine "halte alle Threads an"-Funktion benötigt.
-
Ringding schrieb:
Ja klar, Java.
Also doch schlechtes Design.
-
Ponto schrieb:
Also doch schlechtes Design.
Hehe :D.
-
Ponto schrieb:
Meiner Meinung nach sollte man sich von dem ganzen Signal Zeug fernhalten. Man kann in einem Signalhandler eh nichts richtig sinnvolles machen. Valgrind hatte vor Version 2.4 das Tool helgrind, dass man zum Auffinden von Race Conditions benutzten konnte. Vielleicht hilft es dir.
Leider kann ich Helgrind nicht benutzen, da mein Message-System nichtkopierend arbeitet, und somit Speicher von einem Thread zum andern uebergibt. Dadurch meldet Helgrind pausenlos Race-Conditions, wo gar keine sind. Die Message-Listen habe ich durch Mutex-Semaphoren abgesichert.
Signalhandler muss man so weit ich weiss *IMMER* definieren, wenn man mit mehreren Threads arbeitet, da die pthread-Library Signale benutzt. Deswegen ist es auch unmoeglich, z.B. EINTR zu verhindern (durch Blockieren der Signale).
Doch, man kann Signalhandler dazu benutzen, Event-Objekte zu setzen, die man dann von den Threads aus abfragen kann. SIGIO (SIGPOLL) ist zum Beispiel sehr wichtig fuer TCP/IP-Kommunikation, da das Signal einem sagt, wann man zu pollen hat.
Ich benutze uebrigens auch noch 64-Bit-Asynchrone I/O aus der RT Library.
Heute abend hatte ich noch ein seltsames Problem, ich habe mein Logging-Subsystem so abgeaendert, dass ungepufferte I/O verwendet wird. Manchmal scheint das open64() aber fehlzuschlagen, weil einige Log-Files fehlen. In der Doku steht nix davon, dass bei open64() auch EINTR auftreten kann. Muss ich vielleicht mal checken.
Das ist aber immer noch keine Erklaerung fuer die bizarren Effekte, die ich in meiner Software habe.
Das seltsame ist, SIGSEGV bekomme ich jetzt gar nicht mehr, habe vergeblich versucht, es heute zu reproduzieren. Statt dessen haengen die Threads einfach, auch das Logging haengt, und ich hab keinen Schimmer, warum.
Es zeigt sich jetzt, dass das generell unter Linux 2.4 auftritt, weil auf der Uniprozessor-Kiste mit 2.4 die gleichen Probleme auftreten, wenn die Software eine Weile laeuft. Beim Multiprozessor-System passiert's nur schneller.
Ich kann einfach keinen Fehler im Source finden, aber irgendwo muss noch irgendwas sein. Vielleicht muss ich noch andere Systemaufrufe auf EINTR checken (bislang habe ich nur printf(), fprintf(), read(), write(), close(), recv(), send() usw. gecheckt, also die offensichtlichen).
Vielleicht liegt's auch an meinem Event-System. Was ist eigentlich mit Thread-Local-Storage unter Linux 2.4? Funktioniert das?
Und ich habe gelesen, dass die pthread-Library vor 2.6 sehr buggy sein soll, stimmt das?
-
Ich glaube, das hier ist es:
http://pauillac.inria.fr/~xleroy/linuxthreads/faq.html#J
Notice that all pthread_* functions are not async-signal safe, meaning
that you should not call them from signal handlers. This recommendation
is not to be taken lightly: your program can deadlock if you call a
pthread_* function from a signal handler!The only sensible things you can do from a signal handler is set a
global flag, or call sem_post on a semaphore, to record the delivery of
the signal. The remainder of the program can then either poll the global
flag, or use sem_wait() and sem_trywait() on the semaphore.Another option is to do nothing in the signal handler, and dedicate one
thread (preferably the initial thread) to wait synchronously for
signals, using sigwait(), and send messages to the other threads
accordingly.Meine Event-Funktionen benutzen Mutex-Semaphoren, und da ich im Signal-Handler Events benutze ...
Sch... LinuxThreads!!
Jetzt ist mir auch klar, warum beim 2.6er Kernel scheinbar alles funktioniert -- der pthread-Code wurde von 2.4 auf 2.6 massiv gefixt.
(Die LinuxThreads-Doku hier ist von 1997 und betrifft wohl nur die aelteren Kernel einschliesslich 2.4)Bin mal gespannt, ob's das war!!
-
Naja, das hat schon ein paar gute Gründe, warum es die NPTL gibt.
-
Ringding schrieb:
Hat die Distro schon NPTL? Alles davor ist Mist.
Sieht nicht so aus.
-
nman schrieb:
Naja, das hat schon ein paar gute Gründe, warum es die NPTL gibt.
Wie heisst die Library dafuer? Leider koennen beim Kunden nix installieren. Wenn sie vorhanden ist, kann ich sie benutzen.
-
Das ist keine Library. Das muss in die glibc und in den Kernel eingebaut sein.
-
Ringding schrieb:
Das ist keine Library. Das muss in die glibc und in den Kernel eingebaut sein.
Hmmm ... wie finde ich das raus? Hat der 2.4er Kernel native Threads? Im 2.6er sind sie eingebaut.
D.h. wenn ich zuerst mit der libc linke, muessten die native Threads zuerst drankommen? Leider brauche ich "librt", die wiederum "libpthread" referenziert. Meinst Du, das gibt Probleme?
EDIT: also muesste -lrt -lc funktionieren... das werd ich morgen mal ausprobieren.
-
NPTL ist erst seit Kernel 2.6 dabei. Einige Distributionen haben es aber nach 2.4 portiert gehabt. RedHat 9 lief zum Beispiel schon mit NPTL.
Es gilt aber auch für die neue Implementierung, dass man keine pthread_* Funktionen in Signal Handlern aufrufen darf. Das ist so im PThread Standard so geregelt.
Damit ich keine Signal Handler benutzen muss, nehme ich immer die Lösung mit einem separaten Thread und sigwait, wie es im zitierten Text angedeutet wird.
-
Ponto schrieb:
NPTL ist erst seit Kernel 2.6 dabei. Einige Distributionen haben es aber nach 2.4 portiert gehabt. RedHat 9 lief zum Beispiel schon mit NPTL.
Jup, schön war das aber nicht.
Hat bei mir damals schon ein paar Nachmittage Herumgefluche und nicht eingeplante Überstunden verursacht.