2013-05-15 4 views
0

Je voudrais comprendre le comportement du code suivant. IDAInterface est une librairie avec un membre "myValue".boost: interprocess> managed_shared_memory> différentes valeurs

C++:

#include <boost/interprocess/managed_shared_memory.hpp> 
#include <cstdlib> 

#include <idainterface.h> 

IDAInterface ifIDA; 

int main(int argc, char *argv[]) 
{ 
    using namespace boost::interprocess; 
    typedef std::pair<IDAInterface, int> MyType; // [1] 

    if(argc == 1){ //Parent process 
     struct shm_remove{ 
     shm_remove() { shared_memory_object::remove("MySharedMemory"); } 
     ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } 
     } remover; 
     ifIDA.myValue = 15; 
     managed_shared_memory segment(create_only, "MySharedMemory", 65536); 
     MyType *instance = segment.construct<MyType> ("MyType instance") (ifIDA, 0); 
     std::string s(argv[0]); s += " child "; 
     if(0 != std::system(s.c_str())) return 1; 
     std::cout<<"\nPROZESS 1 "<< ifIDA.myValue; 
     std::cout.flush(); 
     //std::cout<<"\nPROZESS 1 "<< instance->first.myValue; 
     //std::cout.flush(); 
     //segment.destroy<MyType>("MyType instance"); 
     if(segment.find<MyType>("MyType instance").first) return 1; 
    } 
    else{ 
     managed_shared_memory segment(open_only, "MySharedMemory"); 
     std::pair<MyType*, managed_shared_memory::size_type> res; 
     res = segment.find<MyType> ("MyType instance"); 
     if(res.second != 1) return 1; 
     IDAInterface nIFIDA; 
     nIFIDA = res.first->first; 
     std::cout<<"\nPROZESS 2 "<< nIFIDA.myValue; 
     std::cout.flush(); 
     nIFIDA.EineZahl = 10; 
     std::cout<<"\nPROZESS 2 "<< nIFIDA.myValue; 
     std::cout.flush(); 
     segment.destroy<MyType>("MyType instance"); 
    } 
    return 0; 
} 

La sortie:

PROZESS 2 15

PROZESS 2 10

PROZESS 1 15

PROZESS 1 15

Comme je l'ai compris devrait être la valeur dans le processus 1, après avoir exécuté le processus 2, également 10. Pourquoi est dans le processus 1 la valeur de "myValue" toujours 15? Et comment obtenir la valeur modifiée de "myValue" à travers le processus 2 dans le processus 1?

+1

Bienvenue sur StackOverflow. Si possible, veuillez fournir des exemples [sscce] (http://sscce.org/) dans vos questions. Dans ce cas, le code fourni et la sortie spécifiée ne correspondent pas. –

Répondre

0

Je crois que la compréhension de base de Boost.Interprocess est correcte, mais l'implémentation est fausse. Dans ce cas, le processus 2:

  • Crée une copie locale de IDAInterface de la commune IDAInterface exemple. Les modifications apportées à la copie locale ne seront pas observées par d'autres processus.
  • Modifie la mauvaise variable membre. Le processus 1 vérifie myValue, mais le processus 2 modifie EineZahl.

Un autre point à noter est-ce que lors de l'utilisation segment_manager::find(), il faut vérifier la non-nulle de variable membre first de la valeur de retour pour déterminer si l'instance a été trouvée. Dans le cas où l'instance n'a pas été trouvée, la variable membre second sera 1.


Voici un exemple complet où le procédé 1 crée un nombre entier dans un segment de mémoire partagée, le réglage de la valeur à 15. Processus 1 sera ensuite reproduire processus 2, qui va attacher au segment de mémoire partagée, recherchez l'entier et modifiez sa valeur à 10. Une fois le processus 2 terminé, le processus 1 imprime la valeur modifiée.

#include <cstdlib> 
#include <iostream> 

#include <boost/interprocess/managed_shared_memory.hpp> 

const char* segment_name = "MySharedMemory"; 
const char* instance_name = "MyType instance"; 
typedef int my_type; 

int parent_main(const std::string& process) 
{ 
    using namespace boost::interprocess; 
    struct shm_remove { 
    shm_remove() { shared_memory_object::remove(segment_name); } 
    ~shm_remove(){ shared_memory_object::remove(segment_name); } 
    } remover; 

    // Create memory segment. 
    managed_shared_memory segment(create_only, segment_name, 65536); 

    // Create an instance of my_type with a value of 15 in the shared segment. 
    my_type* instance = segment.construct<my_type>(instance_name)(15); 

    // Print value before child. 
    std::cout << "p1 - before child: " << *instance << std::endl; 

    // Spawn child. 
    std::string command = process + " child"; 
    if (0 != std::system(command.c_str())) return 1; 

    // Child has exited, so print the shared instance value. 
    std::cout << "p1 - after child: " << *instance << std::endl; 
    return 0; 
} 

int child_main() 
{ 
    using namespace boost::interprocess; 
    // Attach to shared memory segment. 
    managed_shared_memory segment(open_only, segment_name); 

    // Find the my_type instance in the segment. 
    my_type* instance = segment.find<my_type>(instance_name).first; 

    // If the instance was not found, then return early. 
    if (!instance) return 1; 

    // Value before modifying (initial value set by parent). 
    std::cout << "p2 - begin child: " << *instance << std::endl; 

    // Modify and print value. 
    *instance = 10; 
    std::cout << "p2 - end child: " << *instance << std::endl; 
    return 0; 
} 

int main(int argc, char *argv[]) 
{ 
    return (1 == argc) ? parent_main(argv[0]) : child_main(); 
} 

Sortie:

p1 - before child: 15 
p2 - begin child: 15 
p2 - end child: 10 
p1 - after child: 10 
+0

Je voudrais répondre mais je ne sais pas comment :( Je viens de presser ENTER :) – Earlybite

+0

Je voulais vous dire que j'ai changé ce code à la fois avec ma librairie et cela fonctionne. La sortie est: PROZESS 2 15 PROZESS 2 10 PROZESS 1 15 PROZESS 1 10 Merci beaucoup beaucoup! – Earlybite

Questions connexes