1

リンクされたリストを共有メモリ (C、Linux) に作成することは可能でしょうか。

共有メモリを作成し、このメモリへのポインタを返すライブラリがあるとします。例:

// in lib header
typedef struct _SHM_STR_ {
    int i;
    char c;
} SHM_STR_t;

// in libomg.so
void lib_ret_shmem(SHM_STR_t** shm_pt)
{
    int shm_fd;
    SHM_STR_t *shm_map;

    if ((shm_fd = shm_open(SHM_FILE, (O_CREAT | O_EXCL | O_RDWR), (S_IREAD | S_IWRITE))) > 0) {
        //first time created; init
        ...
    } else if ((shm_fd = shm_open(SHM_FILE, (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE))) < 0) {
        return 1;
    }

    ftruncate(shm_fd, 20*sizeof(SHM_STR_t));

    shm_map = (SHM_STR_t *)mmap(0, 20*sizeof(SHM_STR_t), (PROT_READ | PROT_WRITE), MAP_SHARED, shm_fd, 0)
    ...
    // add new member
    // linked list or work with the offset in the shared mem?
    // increment pointer with offset and return in:
    *shm_pt = shm_map;
}

// in proc1.c something like this
int main(int argc, char *argv[])
{
    SHM_STR_t *ppp = NULL;

    lib_ret_shmem(&ppp);
    printf("%d %c\n", ppp->a, ppp->b);

    return 0;
}

そのため、ライブラリでは、20 個の構造体 SHM_STR_t に十分な共有メモリを割り当てました。

lib_ret_shmem() を呼び出すたびに新しいメンバーを追加する最良の方法は何ですか?

メモリ (または配列) のベース アドレスのオフセットを使用する必要がありますか? メンバーのように[3]のようなものを返します

*shm_pt = shm_map + 3;

または、このメモリにリンクされたリストを作成することは可能ですか? *next が正しいメモリを指していないように感じます。

ひどい説明でごめんなさい:/

4

1 に答える 1

1

リンクされたリストをプロセス間で共有することを意図している場合、リストに新しいノードを作成するために malloc() を使用することはできません。他の割り当てメカニズムが必要になります。すべての割り当てが同じサイズになる場合は、フリー ノード リストから次の割り当てを引き出す特別な shared_malloc() 関数と、ノードをフリー ノード リスト。それはさほど難しいことではありません。共有メモリ プールを作成するときは、大きな mmap 割り当てを必要なサイズのメモリの個々のブロックに分割し (複数のサイズが必要な場合は、それらをすべて最大サイズにします)、それらをすべて初期化します。メモリ範囲内の次の男を指す「次の」ポインターを使用して、「フリーリスト」を割り当てます リストの最初のものへの head ポインタ。別の割り当てが必要なときはいつでも、空きリストの先頭にあるものを取得し、空きリストの先頭ポインタをリストの下の次のものに再割り当てします。

マルチスレッド/マルチプロセス環境でこれを行っている場合 (実際、そうでない場合、なぜ共有メモリを気にするのでしょうか?)、shared_malloc() および shared_free() 関数の同時実行性を考慮する必要があります。 . おそらくセマフォまたはミューテックスを使用します。(プロセス A が次の空きノードを取得したばかりで、まだヘッド ポインターを調整しておらず、プロセス B が中断して空きリストの先頭を取得した場合にどうなるかを考えてみてください... 2 つのプロセスが両方とも同じノードを持っています。 ...)

于 2013-01-29T21:24:12.733 に答える