Zugriffssynchronisation zwischen Threads



  • Ich habe mehrere Threads, die die gleiche Liste von verketteten Elementen modifizieren können. Da es schief gehen würde, wenn mehrere Threads gleichzeitig an den Elementen herumlinken, ist eine Synchronisation nötig, die dafür sorgt, dass immer nur ein Thread das tut. Spontan würde mir folgende Variante einfallen:

    while (ListLocked>0) ThreadSleep(10);
    ListLocked++;
    ...
    ListLocked--;
    

    Nur: angenommen der Thread-Wechsel erfolgt exakt nach der ersten Zeile, dann ist ein zweiter Thread in der Lage, die Schleife ebenfalls zu verlassen, weil ListLocked noch nicht gesetzt wurde. Die Wahrscheinlichkeit ist gering aber es ist nicht unmöglich. Deswegen meine Frage: Gibt es andere Möglichkeiten, so eine Synchronisation zu realisieren, die besser funktionieren?



  • Das Buch "Microsoft Windows- Programmierung für Experten" von Jeffrey Richter beschreibt genau das Problem und seine Lösungsmöglichkeiten...

    Aus dem Kopf fällt mir momentan nur
    EnterCriticalSection

    ein...

    Hier alle Synchronisations-Funktionen in der MSDN

    Ach, InterlockedIncrement() und die entspr. Synchronisationsfunktionen auch...
    Aber mit obigem Link gelangst Du ja zum Thema Thread-Synchronisation in der MSDN...

    /EDIT: Upps, shit, das ist ja ANSI-C Forum hier... args... bitte ignorieren, wäre (wenn überhaupt) WinAPI! SORRY!



  • Naja, allerdings wäre das Betriebssystem schon interessant, denn unter Linux als auch Windows gibts gibts dafür bestimmt irgendwelche Tipps & Tricks. 😃



  • Das ist nicht Standard C, hat als in diesem Forum eigentlich nichts zu suchen

    Die folgenden Mechanismen gibts glaub ich in beiden OS

    Mutex Einen Mutex kann nur einer haben.
    Semaphore Eine Semaphore kann eine definierte anzahl mal vergeben werden
    Events Darauf können mehrere warten

    Für dein Problem bietet sich eine Mutex an. Ich frage des OS ob ich den Mutex bekomme wenn ja bekommt ihn kein anderer mehr. Wenn ich mit meiner Arbiet fertig bin gebe ich den Mutex wieder frei.
    Deshalb setzt man ihn an den Anfang eines Bereichs in dem man sicher sein will das nciht mehrere damit arbeiten. Derjenige der sich an der Liste zu schaffen machen will wartet erst auf den Mutex, wenn er ihn bekommt macht er seine Arbeit danach gibt er den Mutex wieder frei.

    Ein Semaphor ist ähnlich allerdings hat es einen internen Zähle der festlegt wieviele den Semaphor haben können. Dieser Zähler wird von jedem Nutzer um eins erniedrigt. Ist er null kann keiner mehr
    den Semaphor bekommen.

    Ein Event ist ein Signal das irgend jemand setzt. Es können beliebig viel darauf warten. Wenn es einer bekommt (und dies ist rein zufällig) bekommen es die anderen typischerweise nicht mehr.
    Events gibts 2 Sorten, die eine wird zurückgesetzt dadurch das ihn einer bekommt, der andere muß durch einen Funktionsaufruf zurückgesetzt werden, d.h. beliebig viele lönnen ihn bekommen

    Alle 3 Methoden sollten mit einem Timeout ausgestattet werden sonst hängen sich die Porgramme bei gewissen Bedingungen auf.

    Bevor man damit arbeitet sollte man im Windows Bereich die Kapitel in der Hilfe / MSDN dazu gelesen haben. Der Jeffrey Richter sollte auch nicht vergessen weden



  • CarstenJ schrieb:

    Naja, allerdings wäre das Betriebssystem schon interessant, denn unter Linux als auch Windows gibts gibts dafür bestimmt irgendwelche Tipps & Tricks. 😃

    Naja, ich brauche für beide Betriebssysteme eine Lösung.



  • OK, für Linux habe ich es gefunden, da gibts die pthread_mutex_init()/_lock()/_unlock()-Funktionen.



  • das einfachste für windows wäre die critical section ist von der art her wie ein mutex objekt nur irgendwie einfacher 😉 und auch schneller 🙂

    tschöö

    tt



  • TheTester schrieb:

    das einfachste für windows wäre die critical section ist von der art her wie ein mutex objekt nur irgendwie einfacher 😉 und auch schneller

    Einfacher? Schneller? Kannst du das auch sachlich begründen oder wolltest du nur mal wieder rumprollen?



  • nö hat ich nur gelesen einmal in der opengl superbible und dann im petzold, ach warte ich glaub das selbe stand sogar in der msdn...

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/critical_section_objects.asp

    ach ja und wenn du jetzt drauf rumhacken magst das mutex objekte doch eigentlich was anderes sind, ja hast recht sie sind viel komplexer und bieten mehr möglichkeiten, ich persönlich hab eigentlich nur CS objekte benötigt da ich bis jetzt nur threads von einem prozess synchronisieren musste

    bye

    tt



  • Ich wuerde einfach nach einer Library suchen die Threads plattforumunabhaengig kapselt.

    Fuer C kenne ich leider keine - aber ich verschieb es mal nach "Rund um"



  • @TheTester: Ja, und Philip Morris schreibt in seinen Prospekten auch, dass Zigaretten nicht sooo ungesund sind - da muß es ja stimmen! Also dürfte die MSDN auch recht habe, wenn sie behauptet, unter Windows geht es schneller und einfacher.

    Nur komisch: Unter Linux brauche in für die Initialisierung lediglich einen Funktionsaufruf mit ein paar einfachen Parametern - unter Windows muß ich zusätzlich schon eine dümmliche Struktur mit anlegen (dereneinzig sinnvoller Inhalt ein boolean-Member ist - als ob man sowas nicht auch mit einem Flag erschlagen könnte).

    Abfragen eines Lock-States sind unter Linux auch ganz simpel: ein einziger Funktionsaufruf. Unter Windows muss ich die diversen Rückgabewerte (deren Zustände mich gar nicht interessieren) trotzdem überprüfen, weil ich nur bei einem einzigen den Mutex unlocken darf.

    Has du also sonst noch was rumzutrollen?



  • @Barton:
    boost (www.boost.org) hat eine OS-Übergreifende Threading-Bibliothek. Wenn du also mehrere OS unterstützen möchtest, ist es evtl. einfacher, eine solche Bibliothek zu verwenden.

    Übrigens ist bereits das ListLocked++ selbst nicht threadsicher. Vielleicht mal ein, zwei Tutorials reinziehen (z.B.http://www.codeproject.com/threads/sync.asp - nicht sodnerlich, aber ein Anfang)

    @Trolljäger: Whoaaah! Eh du mit deinem großen Trolltotschießgewehr runfuchtelst, mach bitte erstmal deine Hausaufgaben. Das Ding ist gefährlich.



  • peterchen schrieb:

    @Trolljäger: Whoaaah! Eh du mit deinem großen Trolltotschießgewehr runfuchtelst, mach bitte erstmal deine Hausaufgaben.

    Ja bitte? Was war an meinen Aussagen falsch? Kannst du dazu auch was sagen oder gibst du hier auch bloß an?

    Ich kann dir aber sagen, was bei http://www.codeproject.com/threads/sync.asp falsch ist:

    WaitForSingleObject( hMutex, INFINITE );
    for ( i = 0; i < 5; i++ ) a[ i ] = num;
    ReleaseMutex( hMutex );
    

    Das ist laut MSDN ohne Abfrage des Returnwertes von WaitForSingleObject() nämlich schlicht nicht zulässig (siehe http://msdn.microsoft.com/library/en-us/dllproc/base/using_mutex_objects.asp). Also mach erst mal deine Hausaufgaben, bevor du die Leute hier falsch informierst.



  • trolljäger
    **********

    Das ist laut MSDN ohne Abfrage des Returnwertes von WaitForSingleObject()
    nämlich schlicht nicht zulässig

    wo steht das auf der verlinkten seite?

    es stellt sich doch eher die frage ob das so gut ist threads, ohne jegliches error handling, zu synchronisieren, weil es könnte ja passieren das...usw.

    tschööö

    tt

    PS: lasst uns nicht streiten 🙂



  • Das ist laut MSDN ohne Abfrage des Returnwertes von WaitForSingleObject() nämlich schlicht nicht zulässig

    Deswegen hab ich ja gesagt "nicht sonderlich".

    Ja bitte? Was war an meinen Aussagen falsch?

    a) SEUCRITY_ATTRIBUTES ist keine Sinnlose Strukture
    b) in den allermeisten Fällen genügt hier ein NULL-Zeiger
    c) In den meisten Fällen, wo der nicht genügt, genügt eine einmal initialisierte globale struktur
    d) SECURITY_ATTRIBUTES hat zwei Member
    e) ist ja toll das es unter Linux weder ungültige Handles gibt
    f) noch toller ist allerdings, das man den Mutex imemr bekommt - warte, man kann keien Timeout angeben, richtig?
    g) Testers Aussagen bzgl. Mutex vs. Critical Section (unter Windows) sind korrekt - Critical Sections sind einfacher zu verwenden, aber auf einen prozeß beschränkt
    h) Critical Sections unter Windows kommen der oben angegebenen API schon näher.

    Happy crunching. Troll.



  • > a) SEUCRITY_ATTRIBUTES ist keine Sinnlose Strukture

    Nein, aber für das wenige bißchen Inhalt eine eigene Struktur zu spendieren ist schlichtweg übertrieben.

    > b) in den allermeisten Fällen genügt hier ein NULL-Zeiger
    > c) In den meisten Fällen, wo der nicht genügt, genügt eine einmal initialisierte globale struktur

    Schön. Wie hast du das ermittelt? Hast du alle Entwickler gefragt? Und "globale Struktur" klingt ganz toll. Du bist Großmeister in Softwaredesign, gell? LOL!

    > d) SECURITY_ATTRIBUTES hat zwei Member

    Falsch.

    > e) ist ja toll das es unter Linux weder ungültige Handles gibt
    > f) noch toller ist allerdings, das man den Mutex imemr bekommt - warte, man kann keien Timeout angeben, richtig?

    Falsch. Ich empfehle "apropos mutex" und anschließend "man pthread_mutex_..."

    > g) Testers Aussagen bzgl. Mutex vs. Critical Section (unter Windows) sind korrekt - Critical Sections sind einfacher zu verwenden, aber auf einen prozeß beschränkt

    Und damit für die meisten Fälle vermutlich nicht zu gebrauchen!?

    > Troll

    Auweia, das sagt der richtige. Mächtig peinlich, wie weit du dich mit deinem Halbwissen hier aus dem Fenster hängst.



  • a-c) vielleicht weil ich damit arbeite? Weil ich die Anwendungsfälle kenne, unter denen man SECURITY_ATTRIBUTES braucht?
    d) Oh! Oh! Ich hab nLengh vergessen! ich schlimmer ich...

    Ob du die Struktur "sinnvoll" findest oder nicht, ist deine Sache. Und ob CRITICAL_SECTION "nutzlos" ist, überlaß bitte denen, die es verwenden.

    Was ist gegen eine globale SECURITY_ATTRIBUTES(size,NULL,true) einzuwenden? Wenn du mir sagst "das ist niicht OOP" nehm' ich das TROLL zurück und lach ich dich aus.

    Das beste was ich für zum thema pthread_ gefunden habe ist http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html. Ich seh noch nicht was daran so vie toller ist, und wieso man da keine Fehlercodes testen muß, aber naja gut - du wirst das schon wissen.



  • peterchen schrieb:

    Ich seh noch nicht was daran so vie toller ist, und wieso man da keine Fehlercodes testen muß, aber naja gut - du wirst das schon wissen.

    1. "So viel toller/schlechter" stammt nicht von mir - diese Trollaussage darfst du TheTester an den kopf werfen.

    2. Ich habe nie behauptet, dass man keine Fehlercodes testen muß - man kann es sich aber beim lock ersparen, weil das unlock nicht so kritisch ist und returnwert-abhängig behandelt werden muß.

    > Wenn du mir sagst "das ist niicht OOP" nehm' ich das TROLL zurück und lach
    > ich dich aus.

    Wie dumm muß man eigentlich sein, um solche Sachen zu erfinden? Seit wann ist Windows in C++ geschrieben? Hast du es schon mal mit nachdenken probiert, bevor du postest?



  • ähmm...ich glaube hier werden ziemlich inhaltliche dinge verdreht

    1. "So viel toller/schlechter" stammt nicht von mir - diese Trollaussage
    darfst du TheTester an den kopf werfen.

    hab ich nie behauptet, weiterhin hab ich nie etwas über pthreads geschrieben...

    das worauf du dich sicher beziehst, war meine antwort auf deinen post zur msdn 🙂 auf seite 1

    tschöö

    tt



  • @Trolljäger: Pfft.


Anmelden zum Antworten