Frage zur Threadprogrammierung



  • Hi,

    mir ist klar, dass es bei der Threadprogrammierung zu schwer zu findenen Fehlern usw. kommen kann, aber bin mir noch nicht ganz sicher,
    was die Auslöser dafür sind.

    Nehmen wir an ich habe 50 Threads gleichzeitig laufen, die alle eine Referenz auf eine Klasse übergeben bekommen haben.

    Meine erste Frage: Wäre dies bereits gefährlich? Kann die Referenz kaputt gehen?

    Über die Referenz erhält jeder Thread die Möglichkeit Daten auszulesen. Es handelt sich dabei um einen std::vector der Elemente von std::string enthält.
    Ich greife also auf eines dieser Elemente zu.

    Meine zweite Frage: Ist der reine Lesezugriff bereits ein Problem? Kann es zu Komplikationen kommen?

    Nach dem Lesevorgang wird ein weiterer Datensatz hinzugefügt.

    Bei dem Schreibvorgang weiß ich, dass er gefährlich ist und ich diesen entsprechend absichern muss. Aber auch hier habe ich eine Frage: Reicht es, wenn ich das Locken und Unlocken mithilfe eines Mutexes in der Klasse selber durchführe?

    Wäre folgender Pseudo-Code gefährlich?

    class Class
    {
    
     Mutex mutex;
    
     // ...
     std::string read() { return someEntry; }
    
     void write()
     {
      WaitForSingleObject(mutex);
    
      doWriteStuff();
    
      ReleaseMutex(mutex);
     }
    
    };
    
    int main()
    {
     Class theClass;
     run50Threads(theClass);
    }
    
    void run50Threads(Class& c)
    {
     start50ThreadsWithPrameter(c);
    }
    
    void ThreadFunc(void *parameter)
    {
     Class& c= (Class *) parameter; // gefährlich?
    
     while (true)
     {
      c.read(); // gefährlich?
    
      c.write(); // Mutex ist in der Funktion, ist das okay?
     }
    }
    


  • der code ist nicht thread safe. wenn du lesend auf etwas zugreifst was auch von mehreren threads beschrieben werden kann, sind die daten eventuel nicht konsistent waehrend des lesens.
    auch musst du garantieren dass waehrend des ganzen lesens bzw arbeiten auf den daten nicht geschrieben wird. dein return darf also nicht direkt einen string aus dem array zurueckgeben, du musst locken, dann auf eine temporaere var kopieren, dann unlocken und dann zurueckgeben.
    falls deine strings refcounting usw. nutzen, musst du das ebenfalls threadsafe haben.



  • dein return darf also nicht direkt einen string aus dem array zurueckgeben, du musst locken, dann auf eine temporaere var kopieren, dann unlocken und dann zurueckgeben.

    und um das ganze zu vereinfachen, kann man "scoped lock" klassen einsetzen. diese holen sich im ctor den lock, und geben ihn im dtor wieder frei.
    da das kopieren des return-werts VOR dem ausführen des dtors von lokalen variablen erfolgt, ist das OK.
    sieht dann so aus:

    void klasse::funktion()
    {
        scoped_lock lock(m_mutex); // "lock(mutex)"
        return m_blah; // ohne fummelige temporäre variable
    } // "unlock(mutex)"
    

    @asdasdasdasd:
    wie rapso schon schrieb: ist nicht threadsafe.


Log in to reply