Deadlocks absichtlich programmieren



  • Hi,
    ich bin mir zwar im Klaren wie ein Deadlock definiert ist, und wie ein solcher entsteht, doch fehlt mir ein Ansatzpunkt zur Programmierung.
    Ich habe vor 2 Prozesse ablaufen zu lassen, wobei einer zuerst ein txt File reserviert und anschließend den Drucker und ein zweiter Thread zur selben Zeit zuerst den Drucker und dann das txt File reserviert.
    Nun geht es mir um Folgendes: wie ist es möglich eine Ressource zu reservieren? Wenn ich beispielshalber ein Textfile öffne, und dann ein zweiter Prozess versucht das Selbige zu machen, kommt es doch schlichtweg zu einer Access Violation. Hat also jemand einen Hinweis für mich?
    Danke im Voraus.



  • DB bzw. OS?

    MfG SideWinder



  • Windows XP.



  • Ein Deadlock ist ein Laufzeitfehler in einem Programm, der dafür sorgt, dass das Programm nicht mehr weiterläuft. Das kann zum Beispiel auftreten, wenn 2 Threads aufeinander warten und dadurch keiner von beiden jemals signalisiert werden kann.

    Willst du nun den Zugriff auf Drucker und Datei zwischen den zwei Prozessen so regeln, dass nur jeweils ein Prozess darauf zugreifen kann oder willst du diesen Fehler erzeugen, worauf das "absichtlich" in deinem Titel schließen würde?



  • Ich will einen Deadlock wie folgt absichtlich herbeiführen:
    -ProzessA reserviert den Drucker
    -ProzessB reserviert ein Textfile
    -ProzessA versucht nun das Textfile zu reservieren, dass allerdings von ProzessB blockiert wird
    -ProzessB versucht nun den Drucker zu reservieren, der allerdings von ProzessA blockiert wird
    --> Deadlock
    Meine Frage ist nun wie kann ich mittels C++ eine Ressource "reservieren"?



  • gar nicht



  • Dieser Thread wurde von Moderator/in kingruedi aus dem Forum Rund um die Programmierung in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Um den Zugriff auf Ressourcen durch verschiedene Threads zu regeln, werden unter Windows Mutex-Objekte verwendet. Diese Können sich sich immer im Besitz von maximal einem Thread befinden. In der Programmlogik koppelt man dann den Zugriff auf seine Ressource mit dem Besitz des Mutexes.
    Im einfachsten Fall würde man also für Drucker und Textdatei jeweils ein Mutex erstellen, dessen Besitz sich der Thread aneignet, der darauf zugreifen will.

    Unter Windows gibt es dafü die folgenden Funktionen:

    HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitialOwner,LPCTSTR lpName);
    //Erzeugt ein Mutex-Objekt
    
    DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);
    //Im Fall eines Mutex wird der Besitz des Mutex-Objektes angefordert.
    //Der Besitz kann erlangt werden, wenn der Thread, der das Mutex-Objekt
    //momentan im Besitz hat es mit ReleaseMutex freigibt. Der aktuelle Thread
    //wird so lange blockiert bis der Fall eintritt.
    
    BOOL ReleaseMutex(HANDLE hMutex);
    //Der aktuelle Thread gibt das Mutex-Objekt frei.
    
    void ThreadfunktionDie1000MalAufgerufenWird() {
        WaitForSingleObject(FileMutex,INFINITE);
            //Mutex ist jetzt im Besitz, Datei kann beschrieben werden.
        ReleaseMutex(FileMutex); //Fertig mit dem Dateizugriff, Mutex freigeben
    }
    

    In deinem spezifischen Fall kannst du einfach ein Deadlock erzeugen, indem du in Thread A das Drucker-Mutex in Besitz nimmst. Thread B macht das gleiche mit dem Textfile-Mutex. Wenn jetzt beide ihr eigenes Mutex nicht mehr freigeben und auf das andere warten, ist das ein Deadlock. 🙂



  • schreib einfach ein programm mit threads (die fahrzeuge) zum straßenverkehr, vorfahrt von rechts. 4 Autos an einer kreuzung -> deadlock.



  • :p schrieb:

    gar nicht

    #include <stdio.h>
    #include <windows.h>
    
    struct res
    {
       bool locked;
       char *name;      
    };
    
    struct res printer = {false, "printer"};
    struct res textfile = {false, "textfile"};
    
    void getRessource (char *p, struct res *r)
    {    
        printf ("process %s wants %s\n", p, r->name);    
        while (r->locked == true)
        {
           // spin until free
           printf ("process %s locked!!!\n", p);
           Sleep(500);
        }
        r->locked = true;     
        printf ("process %s has %s\n", p, r->name);    
    }
    
    void processA()
    {
       getRessource ("A", &printer);
       getRessource ("A", &textfile);
    }
    
    void processB()
    {
       getRessource ("B", &textfile);
       getRessource ("B", &printer);
    }
    
    int main(int argc, char *argv[])
    {
       while(1)
       {
          processA();
          processB();        
       }
    }
    

Anmelden zum Antworten