【问题标题】:Why are these two addresses not the same?为什么这两个地址不一样?
【发布时间】:2011-03-07 17:41:05
【问题描述】:

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$ 

这一切都很好。但是地址不一样。这是为什么呢?

【问题讨论】:

  • 转化为严肃:在所有问题中,您一直在大声喊叫,而不仅仅是这个问题。如果你有愤怒管理问题,你可能想尽快解决这个问题。你在互联网上的声音越大,就会有越多的人忽略你。
  • 也许我不应该编辑问题来缓和大喊大叫的声音,cmets 这样就很好了。 :)
  • @clintp:如果你愿意,可以回滚 :)
  • @clintp: 别担心我会再次补偿!!!!
  • @BoltClock:非常抱歉。我从来没有心甘情愿地这样做。可能我的英语可能不太好。我问事情的方式不好。但这不是我的性格。如果是这样,我一定会改变自己。

标签: unix shared-memory


【解决方案1】:

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

【讨论】:

  • 请注意,man page 表示同样的事情:“使用 shmat() 且 shmaddr 等于 NULL 是附加共享内存段的首选、可移植方式。请注意附加的共享内存段这种方式可以在不同进程中附加到不同的地址。因此,在共享内存中维护的任何指针都必须是相对的(通常是相对于段的起始地址),而不是绝对的。”
【解决方案2】:

您看到的地址不同,因为它们是虚拟的。每个进程都有一个“假装”的地址空间,该地址空间是连续的(没有间隙),并且可以随着时间的推移而变大。实际上,虚拟地址可以以块的形式映射到 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;0x01 到 0x07 用于 P2)。

【讨论】:

  • 是的,我明白了,谢谢。但是如果我想要相同的物理地址而不是这个不同的逻辑地址(以满足大学教授)有什么办法吗?
  • @pooji:我明白了,谢谢。但是如果我想要相同的物理地址而不是这个不同的逻辑地址(以满足大学教授)有什么办法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多