Boost::SharedMemory ReadModifyWrite



  • Hi,

    wie ist denn das.
    Wenn ich in ein boost shared memory schreibe,
    sind die Schreib/Lese-zugriffe dann atomar ??

    also ein ReadModifyWrite(cmpxchgb) auf einem Shared memory block.

    Gruß



  • So allgemein gefragt? Nein. Es gibt generell recht wenig, was ein Prozess unter der Kontrolle eines Betriebssystems atomisch machen kann, und noch weniger, was plattformunabhängig umsetzbar ist. Atomisches CAS auf ein Maschinenwort ist so die Größenordnung, mit der man da rechnen darf.

    Es gibt aber in Boost.Interprocess eine ganze Reihe von Synchronisationsmechanismen, die man benutzen kann, damit sich zwei Prozesse nicht in die Haare kommen, wenn sie auf dem selben Speicherbereich herumschreiben wollen. Ich lasse man einen Link da. Das läuft in einfachsten Fall ungefähr so:

    // sei shm der shared memory, dann:
    
    struct shared_data {
      boost::interprocess::interprocess_mutex mutex;
    
      // Was du sonst so brauchst. Beispiel:
      int x;
      int y;
      int z;
    };
    
    ...
    
    shared_data *data = new(shm.get_address()) shared_data;
    
    ...
    
    {
      using boost::interprocess::scoped_lock;
      using boost::interprocess::interprocess_mutex;
    
      // Mutex locken; solange das Lock existiert, kann der andere Prozess
      // den Mutex nicht locken und wartet auf seine Freigabe
      scoped_lock<interprocess_mutex> lock(data->mutex);
    
      data->x += 12;
      data->y *= 13;
      data->z -= 14;
    } // Lock wird hier zerstört, jetzt kann der andere Prozess den Mutex locken, wenn er will.
    

    Wichtig ist, dass alle Zugriffe auf den geteilten Speicherbereich durch ein Lock auf den Mutex geschützt sind. Dann greifen die Prozesse nie gleichzeitig darauf zu.



  • Hi seldon,

    danke für die Antwort.

    Das mutex konzept ist mir bekannt.
    Ich brauche aber kein Mutex.

    Mutexe arbeiten auch mit einem readmodifywrite aber
    dort gibt es dann die Möglichkeit einer Verschränkung.
    Oder das hengen in einer Endlosschleife....

    Ich mache einen atomaren Zugriff, und wenn ich ihn nicht bekomme, dann gibt es einen Softwarefehler und das Programm bricht ab.

    Also eher ein Check.

    Das mutex kozept arbeitet zwar auch mit atomaren zugriffen, aber
    das ist eben rein konzeptmäßig anderst. Es wird gewartet, bis auf dem Speicherblock kein prozess mehr arbeitet.
    Kosten: Weniger Speicher auf Kosten von Zeit und der möglichkeit
    in einer Endlosschleife zu hängen.
    Das will ich nicht.

    Ich weiß dass mein Befehl atomar ist.
    Aber ich weiß nicht, wie boost den Speicherbereich abbildet.
    Was genau passiert, wenn ich in boost shared memory schreibe.
    Liegen dahinter nochmal OS aufrufe bei dereferenzieren??

    Kurz - Mir macht sogen dass ich nicht weiß was hinter boost shared memory steckt.

    => ich vermute stark dass einfach ein paging mechanismus verwendet wird, welcher dann in hardware (deskriptoren) gemacht wird.
    Dann ist alles in butter??? - Oder sind zugriffe auf virtuellen speicher nie atomar ???.

    Auf der anderen Seite habe ich in linux über die Strukture file_operations
    mal für zwei prozesse sowas wie ne pipe gebaut.
    Da würde dann bei einem Zugriff ein read()/write() dahinter stecken.
    ...

    Wenn ich das shared memory von boost implementieren sollte, meine ich beide möglichkeiten umsetzen zu können. Und ich finde keine beschreibung, wie es gemacht ist.... Und deswegen bin ich mir unsicher..

    Na ja ev. schau ichs mir mal an...
    Wenn ich einen Windows service mache, und ihn als Treiber anmelde, habe ich ev. zugriff auf die deskriptoren.... aber das ist wieder elend viel arbeit 😞


Anmelden zum Antworten