2013-05-15 2 views
0

Я хотел бы понять поведение следующего кода.boost: interprocess> managed_shared_memory> различные значения

IDAInterface - это библиотека с членом «myValue».

С ++:

#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; 
} 

Выход:

Prozess 2 15

Prozess 2 10

Prozess 1 15

Prozess 1 15

Как я понял, должно быть значение в процессе 1, после запуска процесса 2, также 10. Почему в процессе 1 значение «myValue» всегда равно 15? И как получить измененное значение «myValue» через процесс 2 в процессе 1?

+1

Добро пожаловать в StackOverflow. Когда это возможно, предоставьте в своих вопросах примеры [sscce] (http://sscce.org/). В этом случае предоставленный код и указанный вывод не совпадают. –

ответ

0

Я считаю, что основное понимание Boost.Interprocess верное, но реализация неверна. В этом случае процесс 2:

  • Создаёт локальную копию IDAInterface из общей IDAInterface инстанции. Изменения в локальной копии не будут соблюдаться другими процессами.
  • Изменяет неправильную переменную элемента. Процесс 1 проверяет myValue, но процесс 2 изменяет EineZahl.

Еще один момент отметить это, что при использовании segment_manager::find(), переменная first члена возвращаемого значения должны быть проверен на ненулевой, чтобы определить, является ли экземпляр был найден. В случае, когда экземпляр не найден, переменная-член second будет равна 1.


Вот полный пример, в котором процесс 1 создает целое число в общем сегменте памяти, установив значение 15. Способ 1, то будет порождать процесс 2, который будет прикрепить к общему сегменту памяти, найти целое число , и измените его значение на 10. Как только Process 2 завершает работу, Process 1 печатает измененное значение.

#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(); 
} 

Выход:

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

Я хотел бы ответить, но не знаю, как :( Я просто нажал ENTER :) – Earlybite

+0

Я хотел сказать вам, что я сразу же сменил этот код своей лирикой, и это работает. Выход: PROZESS 2 15 PROZESS 2 10 PROZESS 1 15 PROZESS 1 10 Большое спасибо много! – Earlybite

Смежные вопросы