2011-12-08 14 views
3

这是我的设置...的shmat()函数返回一个不同的 “shmaddr所” 为相同的 “shmkey”

/* 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 

主要:(会fork() “生产者” 和 “消费者” 的过程)

/* 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); 

监制:

/* 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); 

消费者:

/* 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); 

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

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); 
} 

输出:

<*> 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 

这是怎么回事与共享内存地址?如果Main和Prod/Cons进程在他们拥有相同的shmid时附加到不同的shmaddr中,它们又如何?

在此先感谢,

Z @ K!

回答

5

涉及到两组地址。 “芯片RAM地址”(又称硬件,物理地址,实际地址或监控地址)从第一个RAM芯片开始,向上移动。但是,在所有“真正的多任务”操作系统上,每个进程都有自己的“虚拟内存”。 CPU和操作系统协作,为每个进程提供一个“幻觉”,它独立在自己的机器上,拥有自己的地址空间,一张表(在内核和CPU中,取决于体系结构)映射到“虚拟” -process)地址到“真实/硬件/管理员”地址。

共享内存是一种特殊情况,其中从多个进程中寻址相同的“实际内存”。 “shmat”返回的虚拟地址对每个呼叫者都是本地的。

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

+0

我在消费者中发生了错误,并且我使用了不匹配的地址作为景观山羊。就像你所说的那样,它完美地工作。在光明的一面,我学到了一大堆shmget()和shmat()! ;-) – Zak

3

对于在不同进程中虚拟地址处的不同映射相同的共享内存段,这是完全合法的。

2

当进程调用shmat()时,它将返回共享内存的虚拟地址。虚拟地址是当前进程看到的内存位置。不同的进程可以将共享内存映射到进程地址空间中的不同虚拟地址 ,并因此针对不同进程将shmat()调用 的不同返回值映射到进程地址空间中的不同返回值 。

一个很好的图片描述我刚才所说的。 http://poshmodule.sourceforge.net/posh/html/node3.html

相关问题