2

shm.hライブラリを使用して1つの共有メモリブロックを使用して2つの異なる共有を試みています。次の例を作成しました。ここでは、1つの共有メモリブロックが作成され、2つの整数を保持するのに十分な大きさです。次に、それに2つの整数を付加し、2つのプロセスを作成します。最初のプロセスは最初の整数をインクリメントします。次に、2番目のプロセスは2つの整数の値を出力します。しかし、何が起こるかというと、両方の整数が増分されます。

私は何が間違っているのですか?shmライブラリの使い方を学び始めたところです。

これはコードです:

#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>

#include <stdio.h>
#include <unistd.h>

int main() {
  // Declare variables
  int shmID;
  int *data1;
  int *data2;

  // Create a shared memory segment  
  if((shmID=shmget(IPC_PRIVATE, 2*sizeof(int), 0666 | IPC_CREAT))<0)
    {
      fprintf(stderr,"Problem initializing shared memory\n");
      perror("main");
      return -1;
    }

  if((data1=shmat(shmID,NULL,0))==(int *)-1)
    {
      fprintf(stderr,"Problem attaching memory 1\n");
      perror("main");
      return -1;
    }

  if((data2=shmat(shmID,NULL,0))==(int *)-1)
    {
      fprintf(stderr,"Problem attaching memory 2\n");
      perror("main");
      return -1;
    }

  printf("%p %p\n",data1,data2);
  (*data1)=0;
  (*data2)=0;
  if(fork()) 
    { // Process 1 will be the incrementer
      for(int i=0;i<100;i++)
    {
      (*data1)++;
      printf("IN:  %d\n",(*data1));
      sleep(1);
    }
      printf("IN DONE\n");
    }
  else
    {
      while((*data1)<50)
    {
      printf("OUT: %d %d\n",(*data1),(*data2));
      sleep(1);
    }
      printf("OUT DONE\n");
    }
}

そしてこれは出力です:

0x7fcd42a97000 0x7fcd42a96000
IN:  1
OUT: 1 1
IN:  2
OUT: 2 2
IN:  3
OUT: 3 3

私はこれをGentooLinuxで実行しています。

4

2 に答える 2

2

2つの整数はインクリメントされていません。1つの整数がインクリメントされていますが、同じ共有メモリにマップされている2つのプロセスアドレスから整数を出力しています。

システムメモリマネージャは、共有メモリを解決するために舞台裏でいくつかのゲームをプレイします。2つの完全に異なるプロセスでは、共有メモリが各プロセスの2つのまったく異なるアドレスにマップされていることを発見しても驚くことではありません。同じことがここでも起こっています。data1とdata2をそれぞれプロセスアドレス0x7fcd42a97000と0x7fcd42a96000にマッピングしていますが、実際には共有メモリ内の同じものを指しています。

あなたが何をテストしようとしていたか理解できたら、次の行を追加して変更します。

    printf("%p %p\n", data1, data2);

    (*data1) = 0;
    (*data2) = 0;

    int *data3 = data2 + 1; //points 1 int beyond data1 & data2

    (*data3) = 5; //will always print 5

    //............
    printf("OUT: %d %d %d\n", (*data1), (*data2), (*data3));
于 2010-03-10T04:25:08.763 に答える
1

次の2行に気づきました。

if((data1=shmat(shmID,NULL,0))==(int *)-1)

if((data2=shmat(shmID,NULL,0))==(int *)-1)

shmIDが2行間で変更されない場合。これは、 data1data2で同じ共有メモリセグメントを取得していることを意味します。data2が別の共有メモリセグメントを取得できるように、data2用に別のshmIdを作成する必要があります。

于 2010-03-10T03:59:41.613 に答える