Multithreading mit dem GCC



  • Hallo!

    Ich habe folgendes Problem:
    Ich habe eine multi-threaded Anwendung geschrieben - diese übersetzt und arbeitet auch wunderbar auf einem Linux/x86 System. Es starten mehrere Threads und alles ist wunderbar. (Es ist ein Suse 8.1)

    Wenn ich die selbe Anwendung aber auf einer SunOS(5.8)/Sparc Maschine kompiliere und laufen lasse, so werden die einzelnen Threads scheinbar nacheinander abgearbeitet. D.h. der Hauptthread startet mehrere Sub-Threads; der zweite Sub-Thread scheint aber erst genau dann etwas zu tun, wenn er erste Sub-Thread wieder beendet ist. Wenn ich mir das ganze im Debugger anschaue (Totalview & GDB), dann zeigt er mir an, dass nur ein einziger Thread läuft.

    Ich bin momentan ratlos, warum sich das ganze so verhält. Ich vermute eine Compiler-Einstellung beim GCC. Beide GCCs (Linux&Sun) sind mit --enable-threads=posix übersetzt. -D_REENTRANT benutze ich auch. Weitere wichtige Compiler-Einstellung weiß ich leider nicht - 'gcc -v' hat mir auch nicht viel mehr aufschlussreiches ausgespuckt.

    Kennt jemand Gründe für dieses Verhalten oder weiß, ob es noch weitere Switches gibt, die das Multithreading beeinflussen können?

    Gruß



  • Das hat wohl eher mit dem Threading Modell des Betriebssystems zu tun. Ich würde da in einem für SunOS 5.8 oder Threads spezialisiertem Forum nachfragen. Eines, wo ich fragen würde, wäre comp.programming.threads. Aber vielleicht hilft es den Scope auf System zu stellen.



  • Der Grund ist klar: Die POSIX-Threads-Library (pthread) auf Solaris arbeitet kooperativ. Das ist der Nachteil der pthreads-Library, dass sie auch kooperativ implementiert sein kann.

    Entweder Programm mit Conditional Code so umschreiben, dass es die Solaris-Thread-Schnittstelle benutzt, oder eine Version der pthreads-Library besorgen, die das tut. (Oder eine eigene Abstraktionsschicht schreiben)

    Solaris ist ein Sonderfall, da das Multithreading in Solaris generell kaputt ist, viele Systemroutinen sind nicht multithreadfaehig.

    Tja, portable Multithreadanwendungen zu schreiben ist ein Kunststueck fuer sich. 😃 :p

    Ich bin kaum ueberrascht, dass das immer noch so ist...

    pthreads -> Tonne (ausser unter Linux, da gibt's nix anderes)



  • Die pthreads würde ich nicht in die Tonne werfen, die funktionieren ja meistens und was besseres ist noch nicht erfunden worden.

    Ich hab grad gelesen, dass Solaris 2.4 bis Solaris 8 einen Aufruf von pthread_setconcurrency benötigt, da es ein 2-Level Scheduler ist.

    Hier der Usenet Artikel:

    http://groups.google.de/groups?hl=de&lr=&ie=UTF-8&selm=GRFP8.18%24Ua1.93276%40news.cpqcorp.net



  • Es gibt auch die Moeglichkeit, mittels pthread_yield() an strategischen Stellen Rechenzeit abzugaben (fuehrt zur Threadumschaltung bei kooperativen Implementationen).

    Etliche pthreads-Library-Implementationen fuer Solaris und AIX sind "faule Ports", und nutzen nicht die Multithreading-Faehigkeiten des Betriebssystems.

    Die pthreads-Library ist KEIN TEIL von AIX oder Solaris, sondern eine ADD-ON Library.

    Wenn man auf Solaris oder AIX versionsunabhaengig Multithreading benutzen moechte, MUSS man die System-APIs nehmen. Die Thread-Funktionen des Betriebszystems fangen meist mit "thr_" an.

    Beide, AIX und Solaris, verwenden LWPs (Light-Weight-Prozesse, unter Linux "Kernel Threads") die auf die jeweiligen Prozessoren gescheduled werden. Ein Thread unter AIX und Solaris ist ein LWP.

    Von den beiden hat nur AIX hat ein ordentliches Multithreading. Bei Solaris sind, wie bereits erwaehnt, etliche Systemroutinen nicht multithreadfaehig, ausserdem ist eine Signalzustellung an Threads unmoeglich, und weitere Designfehler. Kann sein, dass die bei neueren Versionen behoben wurden, weiss ich aber nicht. Die letzten Solaris-Versionen auf der ich programmiert habe, waren Solaris 7 und 8.

    Vielleicht war das der Grund, warum die pthreads-Library auf diesen Solaris-Versionen kooperativ arbeitet. Kooperatives Multitasking ist aber fuer die Praxis so gut wie unbrauchbar, da kann man seine Funktionen gleich selber abwechselnd aufrufen.

    Kooperative Scheduler sind total veraltet und wurden bei den alten MacOS-Versionen (vor MacOS 😵 und bei Windows 3.0, 3.1, sowie unter DOS verwendet.

    Jedes normale Betriebssystem hat einen praeemptiven Scheduler, auch Solaris.



  • Vielen Dank für die Antworten. Wenn das Threading kooperativ funktioniert, erklärt das schonmal einiges. Ich werde mal versuchen, mit der Lösung im geposteten Link zurechtzukommen.

    Weiß jemand, ob ich unter einem Tru64 (5.1b) System auf ähnliche Probleme stoßen werde?

    Vielen Dank und Gruß!


Anmelden zum Antworten