问题
Here's my setup...
/* 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
Main: (will fork() the "Producer" and "Consumer" processes)
/* 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);
Producer:
/* 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);
Consumer:
/* 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);
Error testing: (for the sake of brevity...)
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);
}
Output:
<*> 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
What is going on with the shared memory address? How are Main and the Prod/Cons processes getting different shmaddr when they attach when they have the same shmid?
Thanks in advance,
Z@K!
回答1:
There are two sets of addresses involved. The "Chip RAM addresses," aka hardware, physical, real, or supervisor addresses, start at your first RAM chip at 0 and move upwards. However, on all "true multi-tasking" operating systems, each process gets its own "virtual memory." The CPU and OS collaborate to give each process the "illusion" that it is alone on its own machine, with its own address space, with a table (in the kernel and CPU, depending on architecture) mapping from the "virtual" (per-process) addresses to the "real/hardware/supervisor" addresses.
Shared memory is a special case, where the same "real memory" is addressed from more than one process. The virtual addresses that "shmat" returns are local to each caller.
Likewise, when you load a shared object (.so) library, it may be mapped into a different address space in each process.
回答2:
It's perfectly legal for the same shared memory segment to be mapped at different virtual addresses in different processes.
回答3:
when a process calls shmat(), it will return the virtual address of the shared memory. virtual address is the memory location as seen by the current process. different process can map the shared memory to different virtual address in the process address space and hence different return values of shmat() call for different processes.
a nice pictorial description of what I just said above. http://poshmodule.sourceforge.net/posh/html/node3.html
来源:https://stackoverflow.com/questions/8434974/shmat-is-returning-a-different-shmaddr-for-same-shmkey