LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-24-2011, 04:12 AM   #1
Nerdio
LQ Newbie
 
Registered: Sep 2011
Posts: 27

Rep: Reputation: Disabled
Linux : Shared memory start addresses differ


I have cribbed some code from here , and it seems to run just fine.

I then went on to adapt this to be a little closer to my needs, and ran into problems. One of the first things I spotted is that the 'apparent' start address of the shared memory segments differ between client and server.

Here is my code. (There is some redundant stuff I know cos I have worked it back from my adapted version to a basic version).

shm_server.c

Code:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "lock_jrn.h"

int main(int argc, char **argV)
{
    char c;

    int shmid;

    int count;
    int idx;
    int next;
    int seqNo = MIN_SEQ_NO;
    size_t sz;

    key_t key;
    char *shm, *s;
    char *start;

    struct lock_jrn_str jrn;

    /*
     * We'll name our shared memory segment
     * "5678".
     */
    key = SHM_KEY;

    // Create the segment.

    sz = BUFFER_SIZE;//(size_t)(MAX_MSGS * sizeof(struct lock_jrn_str));

    if ((shmid = shmget(key, sz, IPC_CREAT | 0666)) < 0)
    {
        perror("shmget");
        exit(errno);
    }

    // Now we attach the segment to our data space.
    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)
    {
        perror("shmat");
        exit(1);
    }

    // Now put some things into the memory for the
    // other process to read.
    s = shm;
    start = s;

    printf("Start Address is %p. Size is %x\n", s, sz);
    for (c = 'a'; c <= 'z'; c++)
    {
        *s++ = c;
    }

    *s = '\0';//NULL;

    /*
     * Finally, we wait until the other process
     * changes the first character of our memory
     * to '*', indicating that it has read what
     * we put there.
     */
    while (*shm != '*')
        sleep(1);

    exit(0);
}
shm_client.c

Code:
/*
shm-client - client program to demonstrate shared memory.
*/
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "unistd.h"

#include "lock_jrn.h"

#define SHMSZ     27

char *shm;
char *start;

int main(int argc, char **argv)
{
    int shmid;
    key_t key;
    char *s;

    int idx;
    size_t sz;
    struct lock_jrn_str jrn;

    /*
     * We need to get the segment named
     * "5678", created by the server.
     */
    key = SHM_KEY;

    /*
     * Locate the segment.
     */

    sz = BUFFER_SIZE;//MAX_MSGS * sizeof(struct lock_jrn_str);

    if ((shmid = shmget(key, sz, 0666)) < 0) {
        perror("shmget");
        exit(1);
    }

    /*
     * Now we attach the segment to our data space.
     */
    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
        perror("shmat");
        exit(1);
    }

    start = shm;
    s = shm;
    printf("Start Address is %p. Size is %x\n", s, sz);

    /*
     * Now read what the server put in the memory.
     */
    for (s = shm; *s != '\0'; s++)
        putchar(*s);
    putchar('\n');

    /*
     * Finally, change the first character of the
     * segment to '*', indicating we have read
     * the segment.
     */
    *shm = '*';

    exit(0);
}
lock_jrn.h

Code:
#define MIN_SEQ_NO 1
#define MAX_SEQ_NO 999999
#define MAX_MSGS    50
#define SHM_KEY     1358
#define BUFFER_SIZE   (size_t)(MAX_MSGS * sizeof(struct lock_jrn_str));

struct lock_jrn_str
{
    int seqNo;
    int next;
    char data[50];
};
~

What I get out is this....

> ./shm_server
Start Address is 0xb75f9000. Size is bb8

> ./shm_client
Start Address is 0xb75f6000. Size is bb8
abcdefghijklmnopqrstuvwxyz

The result is correct, so no complaints there, but I do not understand why the start addresses are different. I thought the memory was shared, so was physically the same block. Or is there something a little cleverer going on in the background, and the memory is mirrored or something.

Can someone throw some light on this? I am curious.

As I say I have adapted this back from a more complex version, so please ignore the redundant code.

Thanks
 
Old 11-24-2011, 04:34 AM   #2
SigTerm
Member
 
Registered: Dec 2009
Distribution: Slackware 12.2
Posts: 379

Rep: Reputation: 234Reputation: 234Reputation: 234
Quote:
Originally Posted by Nerdio View Post
The result is correct, so no complaints there, but I do not understand why the start addresses are different. I thought the memory was shared, so was physically the same block. Or is there something a little cleverer going on in the background, and the memory is mirrored or something.
Pointer value is not an address within physical memory, it is a virtual memory address. Operating system can relocate program to a different place within physical memory, and pointer value won't change. It is protected mode feature. See "logical address".

Last edited by SigTerm; 11-24-2011 at 04:37 AM.
 
Old 11-24-2011, 04:47 AM   #3
Nerdio
LQ Newbie
 
Registered: Sep 2011
Posts: 27

Original Poster
Rep: Reputation: Disabled
That makes a lot of sense. Thanks for that.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to create a shared memory and some shared objects in linux? jeremy28 Programming 6 06-11-2010 05:21 AM
symbol addresses differ between vmlinux and /proc/kcore jdoyle1 Linux - Kernel 1 09-09-2009 04:55 PM
Linux shared memory segment access problem and x86 Virtual Memory layout. regmee Linux - Kernel 1 08-23-2008 12:11 AM
mechanics of mapping process memory addresses to physical addresses on amd64 Tischbein Linux - Kernel 2 02-01-2007 08:09 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:38 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration