shmat()为同一个"shmkey"返回一个不同的"shmaddr"

Zak*_*Zak 3 c posix producer-consumer shared-memory

这是我的设置......

/* Bounded Buffer item structure */
struct item {
    int  id;  /* string index value */
    char str[80];  /* string value */
};

/* Structure for the shared memory region */
typedef struct {
    int    debug;           /* debug flag */
    int    in;              /* index of next empty slot */    
    int    out;             /* index of next full slot  */
    char   MUTEXname[32];   /* name of the MUTEX semaphore */
    char   EMPTYname[32];   /* name of the EMPTY semaphore */
    char   FULLname[32];    /* name of the FULL semaphore  */
    struct item buff[BUFFSIZE];  /* circular buffer for producer/consumer items*/
    char   strarray[MAX_STRINGS][80]; /* shared array of strings for consumers */
} shr_mem_t;

/* Values for obtaining a shmid key via ftok() */
#define KEYPATH "."
#define KEYPROJ 4520
Run Code Online (Sandbox Code Playgroud)

Main :(将fork()"Producer"和"Consumer"进程)

/* Use ftok() to get a value for a key to identify a shared memory segment */
shm_key = ftok(KEYPATH, KEYPROJ);

/* Create the shared memory segment */
shmid = shmget(shm_key, sizeof(shr_mem_t), IPC_CREAT | IPC_EXCL | 0660);

/* Attach shared memory segment to the parent process */
shmptr = shmat(shmid, NULL, 0);
Run Code Online (Sandbox Code Playgroud)

制片人:

/* Use ftok() to get value for the key to identify the shared memory segment */
shm_key = ftok(KEYPATH, KEYPROJ);

/* Get the ID of the existing shared memory segment */
shmid = shmget(shm_key, sizeof(shr_mem_t), 0660);

/* Attach the shared memory segment */
shmptr = shmat(shmid, NULL, 0);
Run Code Online (Sandbox Code Playgroud)

消费者:

/* Use ftok() to get value for the key to identify the shared memory segment */
shm_key = ftok(KEYPATH, KEYPROJ);

/* Get the ID of the existing shared memory segment */
shmid = shmget(shm_key, sizeof(shr_mem_t), 0660);   

/* Attach the shared memory segment */
shmptr = shmat(shmid, NULL, 0);
Run Code Online (Sandbox Code Playgroud)

错误测试:(为了简洁起见......)

if (shmid == -1) {
    perror("shmget failed in __________");
    exit(1);
} else {
    sprintf(errString, "<*> __________ shared memory id: %i ", shmid);
    perror(errString);
}

if(shmptr == (void *)(-1)) {
    perror("shmat failed in __________");
    exit(1);
} else {
    sprintf(errString, "<*> __________ attaching to shared memory address: %p ", shmptr);
    perror(errString);
}
Run Code Online (Sandbox Code Playgroud)

输出:

<*> Main creating shared memory id: 101376 : No such file or directory
<*> Main attaching to shared memory address: 16000 : No such file or directory
Creating the producer and consumer processes...
<*> Producer located shared memory id: 101376 : Successful
<*> Consumer located shared memory id: 101376 : Successful
<*> Producer attaching to shared memory address: 10000 : Successful
<*> Consumer attaching to shared memory address: 10000 : Successful
Run Code Online (Sandbox Code Playgroud)

共享内存地址发生了什么?Main和Prod/Cons如何处理当他们有相同的shmid时附加的shmaddr?

提前致谢,

ž@ķ!

BRP*_*ock 5

涉及两组地址."芯片RAM地址",也就是硬件,物理,实际或超级用户地址,从第一个RAM芯片开始,为0并向上移动.但是,在所有"真正的多任务"操作系统中,每个进程都有自己的"虚拟内存".CPU和操作系统协作为每个进程提供单独在自己的机器上的"幻觉",具有自己的地址空间,具有从"虚拟"映射的表(在内核和CPU中,取决于体系结构)(每个进程) -process)地址到"真实/硬件/管理员"地址.

共享内存是一种特殊情况,其中从多个进程处理相同的"实内存"."shmat"返回的虚拟地址是每个调用者的本地地址.

同样,当您加载共享对象(.so)库时,它可能会映射到每个进程中的不同地址空间.