为什么这两个地址不一样?

时间:2011-03-07 17:41:06

标签: unix shared-memory

shmget.c:

#include<sys/types.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>
main()
{
    key_t key;
    int shmid;
    char* addr1;
    key = ftok("/home/tamil/myc/pws.c",'T');
    shmid = shmget(key,128*1024,IPC_CREAT|SHM_R|SHM_W);

    addr1 = shmat(shmid,0,0);

    printf("\nIPC SHARED MEMORY");
    printf("\n SENDER ADDRESS");
    printf("\nTHE ADDRESS IS %p",addr1);
    printf("\nENTER THE MESSAGE:");
    scanf("%s",addr1);
    printf("\nMESSAGE STORED IN %p IS %s",addr1,addr1);  
}

shmget2.c:

#include<sys/types.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>

main()
{
    int shmid;
    char* addr1;
    key_t key;


    key = ftok("/home/tamil/myc/pws.c",'T');
    shmid = shmget(key,128*1024,SHM_R|SHM_W);

    addr1 = shmat(shmid,0,0);


    printf("\nIPC SHARED MEMORY");
    printf("\n SENDER ADDRESS");
    printf("\nTHE ADDRESSS IS %p",addr1);
    printf("\nMESSAGE STORED IN %p IS %s",addr1,addr1);

}

输出:

tamil@ubuntu:~/myc$ cc shmget.c
tamil@ubuntu:~/myc$ ./a.out

IPC SHARED MEMORY
 SENDER ADDRESS
**THE ADDRESS IS **0xb786c000****
ENTER THE MESSAGE:helloworld

MESSAGE STORED IN **0xb786c000** IS helloworldtamil@ubuntu:~/myc$ cc shmget2.c
tamil@ubuntu:~/myc$ ./a.out

IPC SHARED MEMORY
 SENDER ADDRESS
**THE ADDRESSS IS **0xb7706000****
MESSAGE STORED IN **0xb7706000** IS helloworldtamil@ubuntu:~/myc$ 

这一切都运作良好。但地址不一样。这是为什么?

2 个答案:

答案 0 :(得分:6)

共享内存可以映射到不同进程的地址空间中的不同区域。这是完全正常的。但是如果你将共享内存中的指针存储到共享内存的其他部分,那么你就麻烦了。在这种情况下,您需要使用类似offset pointer的内容。

答案 1 :(得分:1)

您看到的地址不同,因为它们是虚拟。每个进程都会获得一个“假装”地址空间,该地址空间是连续的(无间隙),并且可以随着时间的推移变大。实际上,虚拟地址可以以块的形式映射到RAM的不同部分。有关更多详细信息,请查看here(特别是this diagram)。在共享内存的情况下,两个进程都可以“看到”单个RAM区域。但是,地址看起来与每个过程看起来不同是完全正常的。

以下是这个想法:

                      0x00   0x01             0x07               0xff         
 Process 2 Virtual:       +--+-----------------+------------------+
                             |                 |
 RAM Physical Addr:     0x04 +-----shared------+ 0x0a
                             |                 | 
 Process 1 Virtual:  +-------+-----------------+---------+
                    0x00    0x09              0x0f       0xff

(未按比例绘制:)请注意,进程1和2共享相同的RAM区域(物理地址0x04到0x0a),但该共享的RAM映射到其虚拟地址空间的不同部分(0x09到0x0f)对于P1;对于P2,为0x01到0x07)。