4

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 OSXでboost1.47.0を使用しています。バグですか?それを修正するために、いくつかの設定でいくつかのマクロを使用する必要がありますか?誰かが以前にこの問題に遭遇したことがありますか?

4

2 に答える 2

1

私は問題の解決策を見つけました、そして予想通りそれはバグです。

このバグは、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)

このバグを後押しするためにチケットを作成しました。

ありがとうございました。

于 2011-10-25T08:58:15.167 に答える
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がその実装で使用するものです。

于 2011-10-24T23:05:16.367 に答える