0

複数のリーダーとライターがアクセスできるように、共有メモリ セグメントを作成する必要があります。セマフォとリーダーとライターに関する限り、私は自分が何をしているのかを知っていると思います...

しかし、共有メモリセグメントを作成する方法についてもわかりません。セグメントが 20 個の構造体の配列を保持するようにします。各構造体は、名、int、および別の int を保持します。

少なくともこれを開始するのを手伝ってくれる人はいますか? 私は必死で、オンラインで読んだものすべてが私をさらに混乱させます.

編集:さて、私はこのようなことを始めます

int memID = shmget(IPC_PRIVATE, sizeof(startData[0])*20, IPC_CREAT);

初期化されたデータを保持する構造体の配列として startData を使用すると、「セグメンテーション違反 (コア ダンプ)」というエラーが表示されます。

4

1 に答える 1

1

共有メモリを取得する最新の方法は、Single UNIX Specification で提供されている API を使用することです。以下は 2 つのプロセスの例です。1 つは共有メモリ オブジェクトを作成して内部にデータを配置し、もう 1 つはそれを読み取ります。

最初のプロセス:

#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>

#define SHM_NAME "/test"

typedef struct
{
   int item;
} DataItem;

int main (void)
{
   int smfd, i;
   DataItem *smarr;
   size_t size = 20*sizeof(DataItem);

   // Create a shared memory object
   smfd = shm_open(SHM_NAME, O_RDWR | O_CREAT, 0600);
   // Resize to fit
   ftruncate(smfd, size);
   // Map the object
   smarr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, smfd, 0);

   // Put in some data
   for (i = 0; i < 20; i++)
      smarr[i].item = i;

   printf("Press Enter to remove the shared memory object\n");
   getc(stdin);

   // Unmap the object
   munmap(smarr, size);
   // Close the shared memory object handle
   close(smfd);
   // Remove the shared memory object
   shm_unlink(SHM_NAME);

   return 0;
}

このプロセスは、 で共有メモリ オブジェクトを作成しますshm_open()。オブジェクトは初期サイズ 0 で作成されるため、 を使用して拡大されftruncate()ます。次に、オブジェクトは、 を使用してプロセスの仮想アドレス空間にメモリ マップされますmmap()。ここで重要なことは、マッピングが読み取り/書き込み ( PROT_READ | PROT_WRITE) であり、共有 ( MAP_SHARED) であることです。マッピングが完了すると、通常の動的に割り当てられたメモリとしてアクセスできます (実際のところmalloc()glibcLinux ではより大きな割り当てに匿名メモリ マッピングを使用します)。次に、プロセスはデータを配列に書き込み、Enter キーが押されるまで待機します。次に、 を使用してオブジェクトのマップmunmap()を解除し、ファイル ハンドルを閉じて、 でオブジェクトのリンクを解除しますshm_unlink()

2 番目のプロセス:

#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>

#define SHM_NAME "/test"

typedef struct
{
   int item;
} DataItem;

int main (void)
{
   int smfd, i;
   DataItem *smarr;
   size_t size = 20*sizeof(DataItem);

   // Open the shared memory object
   smfd = shm_open(SHM_NAME, O_RDONLY, 0600);
   // Map the object
   smarr = mmap(NULL, size, PROT_READ, MAP_SHARED, smfd, 0);

   // Read the data
   for (i = 0; i < 20; i++)
      printf("Item %d is %d\n", i, smarr[i].item);

   // Unmap the object
   munmap(smarr, size);
   // Close the shared memory object handle
   close(smfd);

   return 0;
}

これは、共有メモリ オブジェクトを読み取りアクセス専用に開き、読み取りアクセス専用にメモリ マップします。配列の要素に書き込もうとするとsmarr、セグメンテーション違反が発生します。

最初のプロセスをコンパイルして実行します。次に、別のコンソールで 2 番目のプロセスを実行し、出力を観察します。2 番目のプロセスが終了したら、最初のプロセスに戻り、Enter キーを押して共有メモリ ブロックをクリーンアップします。

詳細については、各関数のマニュアル ページまたは SUS のメモリ管理部分を参照してください (これらの関数のシステム固有の動作が文書化されているため、マニュアル ページを参照することをお勧めします)。

于 2012-11-21T21:52:52.350 に答える