2010-03-10 112 views
2

我試圖使用shm.h庫共享兩個不同的使用一個共享內存塊。我寫了下面的例子,其中一個共享內存塊被創建並且足夠大以容納兩個整數。然後我附加兩個整數並創建兩個進程。第一個過程增加第一個整數。第二個過程然後打印出兩個整數的值。但是會發生什麼呢是兩個整數都會增加。通過sys/shm.h共享多個變量

我在做什麼錯?我剛開始學習如何使用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 

我在Gentoo Linux上運行此。

回答

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)); 
+0

謝謝你,這工作。 – kkrizka

1

我注意到以下兩行:

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

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

的shmid不會卡在兩條線之間改變。這意味着您正在爲data1data2獲得相同的共享內存段。您需要爲data2創建另一個shmId,以便data2獲取不同的共享內存段。