【问题标题】:Reading Shared Memory from x86 to x64 and vice versa on OSX在 OSX 上从 x86 读取共享内存到 x64,反之亦然
【发布时间】:2011-12-14 04:18:07
【问题描述】:

如果我从 64 位应用程序创建 SM 并在 32 位应用程序上打开它会失败。

//for 64 bit
    shared_memory_object( create_only, "test" , read_write) ; 
// for 32 bit
    shared_memory_object (open_only, "test", read_write);

64位应用创建的文件路径如下:

/private/tmp/boost_interprocess/AD21A54E000000000000000000000000/test

32 位应用程序搜索的文件在路径中的位置

/private/tmp/boost_interprocess/AD21A54E00000000/test

因此 32 位应用程序无法读取该文件。

我在 Mac OS X 上使用 boost 1.47.0。 它是一个错误吗?我是否必须使用某些宏进行一些设置才能修复它?有没有人遇到过这个问题?

【问题讨论】:

    标签: c++ macos boost shared-memory boost-interprocess


    【解决方案1】:

    文件支持共享内存是否重要?如果没有,您可以考虑使用底层的 Unix 共享内存 API:shmget、shmat、shmdt 和 shmctl,它们都在 sys/shm.h 中声明。我发现它们非常易于使用。

    // create some shared memory
    int id = shmget(0x12345678, 1024 * 1024, IPC_CREAT | 0666);
    
    if (id >= 0)
    {
        void* p = shmat(id, 0, 0);
    
        if (p != (void*)-1)
        {
            initialize_shared_memory(p);
    
            // detach from the shared memory when we are done;
            // it will still exist, waiting for another process to access it
            shmdt(p);
        }
        else
        {
            handle_error();
        }
    }
    else
    {
        handle_error();
    }
    

    另一个进程会使用这样的东西来访问共享内存:

    // access the shared memory
    int id = shmget(0x12345678, 0, 0);
    
    if (id >= 0)
    {
        // find out how big it is
        struct shmid_ds info = { { 0 } };
    
        if (shmctl(id, IPC_STAT, &info) == 0)
            printf("%d bytes of shared memory\n", (int)info.shm_segsz);
        else
            handle_error();
    
        // get its address
        void* p = shmat(id, 0, 0);
    
        if (p != (void*)-1)
        {
            do_something(p);
    
            // detach from the shared memory; it still exists, but we can't get to it
            shmdt(p);
        }
        else
        {
            handle_error();
        }
    }
    else
    {
        handle_error();
    }
    

    然后,当所有进程都使用共享内存时,使用shmctl(id, IPC_RMID, 0) 将其释放回系统。

    您可以在命令行中使用 ipcs 和 ipcrm 工具来管理共享内存。它们对于在首次编写共享内存代码时清理错误很有用。

    话虽如此,我不确定在 32 位和 64 位程序之间共享内存。我建议尝试 Unix API,如果失败,可能无法完成。毕竟,它们是 Boost 在其实现中使用的。

    【讨论】:

    • 对不起。我不能使用原生 Unix 共享内存 API,因为我必须保持代码跨平台。
    • @Rahul,您的目标是哪些平台?
    • WIN XP/VISTA/7 & MAC OS 10.6/7
    • 谢谢,@Rahul。好吧,至少你发现并解决了问题。很好的收获。
    【解决方案2】:

    我找到了问题的解决方案,不出所料,这是一个错误。

    此错误存在于 tmp_dir_helpers.hpp 文件中。

        inline void get_bootstamp(std::string &s, bool add = false)
        {
          ...
           std::size_t char_counter = 0;
           long  fields[2] = { result.tv_sec, result.tv_usec };
           for(std::size_t field = 0; field != 2; ++field){
              for(std::size_t i = 0; i != sizeof(long); ++i){
                 const char *ptr = (const char *)&fields[field];
                 bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4];
                 bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)];
              }
           ...
        }
    

    应该是这样的..

    **long long** fields[2] = { result.tv_sec, result.tv_usec };
               for(std::size_t field = 0; field != 2; ++field){
                  for(std::size_t i = 0; i != sizeof(**long long**); ++i)
    

    我为这个错误创建了一个ticket

    谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-11
      • 2020-03-27
      • 1970-01-01
      • 2016-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-21
      相关资源
      最近更新 更多