Shared Memory...Some Questions..... - Linux

This is a discussion on Shared Memory...Some Questions..... - Linux ; All, I having trouble getting a simple example of a shared memory example to work; I have never worked with shared memory and any suggestions/code hints/ examples would be greatly appreciated. >From my reading you have to use shmget to ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: Shared Memory...Some Questions.....

  1. Shared Memory...Some Questions.....

    All,
    I having trouble getting a simple example of a shared memory example
    to work;

    I have never worked with shared memory and any suggestions/code hints/
    examples would be greatly appreciated.

    >From my reading you have to use shmget to specify that you need a

    specific size of memory to be shared and then you use shmat to attach
    it to a specific process.

    My thinking, which is flawed, is that the child adding the 1099 to
    what I believe the shared integer variable would then be "shared" to
    the parent's final output of the procee id and the shared variable
    ( cout<<"Parent "< when ran for the parents final output is not 1099 but is the value
    99.

    int main (void)
    {
    int indexId = 0;

    if((indexId = shmget(IPC_PRIVATE,sizeof(int),SHM_R|SHM_W))<0)
    {
    cout<<"ERROR: indexId ="< cout< exit (1);
    }

    int ptheSharedIndex;
    ptheSharedIndex = (int)shmat(indexId,0,0); //attach to the current
    process
    ptheSharedIndex = 99;

    int k = 0;
    while (k {
    pid = 0;
    k=k+1;
    pid = fork();
    if (pid == 0)
    {break;}
    }

    if (pid == 0) /* child process */
    {
    int indexIdChild = 0;
    if((indexIdChild = shmget(key,sizeof(int),SHM_R|SHM_W))<0)
    {
    cout<<" CHILD ERROR: indexIdChild "< }
    int ctheSharedIndex;
    ctheSharedIndex = (int)shmat(indexIdChild,0,0);
    */
    /* int ctheSharedIndex;
    ctheSharedIndex = (int)shmat(indexId,0,0);*/
    cout< ptheSharedIndex = 1099;
    }

    else /* parent */
    {
    sleep(8);
    cout<<"Parent "< }

    exit(0); //End Process (Main)
    }

    Thanks for the help,
    Chris


  2. Re: Shared Memory...Some Questions.....

    Solomon_Man wrote:
    > int indexId = 0;
    > if((indexId = shmget(IPC_PRIVATE,sizeof(int),SHM_R|SHM_W))<0)
    > {
    > cout<<"ERROR: indexId ="< > cout< > exit (1);
    > }


    You have an error in you method of programming here, in particular for C++
    you could do better. Suggestion:

    int shm_create( size_t size, int flags)
    {
    int res = shmget( IPC_PRIVATE, size, flags);
    if(res!=-1)
    return res;
    int const e = errno;
    cout << "shmget() failed, errno=" << e << '(' << strerror(e) << ")\n";
    exit(EXIT_FAILURE);
    }

    What's the difference?
    1. You are doing things between shmget() and reading errno that might
    affect errno. Save the value immediately!
    2. Use EXIT_FAILURE, it documents clearly what is going on.
    3. No need to init a variable to zero and then assign a value to it. In
    fact I'd consider the if-clause pretty unreadable. Suggestion:
    int indexId = shmget(...);
    if(indexId == -1)
    { ... }

    What else:
    The function returns an int, but that is in fact a resource handle that can
    be used to access the shared memory. You need to make sure that this
    resource is correctly released after use. For that, use RAII (STW if that
    doesn't mean anything to you yet). I would suggest you create a wrapper
    that behaves like std::auto_ptr, all with its peculiar copying semantics.
    With that in place, you could also use exceptions to signal errors which
    makes the final code much, much clearer.

    > int ptheSharedIndex;
    > ptheSharedIndex = (int)shmat(indexId,0,0);
    > //attach to the current process


    Now, this is plainly wrong: You are casting a pointer to an integer. Do you
    know the difference between a pointer-to-X and an X? Further, the rule is
    to never use C style casts in C++. If you don't (yet) understand why, at
    least accept this for now and don't stray from this path. FYI, the correct
    cast is a static_cast and if you try to cast to the wrong type the
    compiler will tell you about it as good as it can - the 'int' would have
    been flagged as error.

    > exit(0); //End Process (Main)


    Unnecessary, you could have returned here or simply fallen off the end with
    the same effect.

    Uli


  3. Re: Shared Memory...Some Questions.....

    "Solomon_Man" wrote in
    news:1174442771.089368.296510@b75g2000hsg.googlegr oups.com:

    I'm by no means a shared memory expert...

    > if (pid == 0) /* child process */
    > {
    > int indexIdChild = 0;
    > if((indexIdChild =
    > shmget(key,sizeof(int),SHM_R|SHM_W))<0)
    > {
    > cout<<" CHILD ERROR: indexIdChild "< > }


    A few things here...

    Where does "key" come from? I did not see it declared prior to this
    point. Same with

    Attached memory segments are inherited across a fork, so you
    shouldn't have to repeat the shmget/shmat in the children.

    You specified IPC_PRIVATE as the key when you first called shmget
    before the fork. If you want to be able to shmget the same segment
    in another process, you neet to use the same key in all shmgets and
    that key cannot be IPC_PRIVATE.

    > int ctheSharedIndex;
    > ctheSharedIndex = (int)shmat(indexIdChild,0,0);
    > */
    > /* int ctheSharedIndex;
    > ctheSharedIndex = (int)shmat(indexId,0,0);*/
    > cout< > ptheSharedIndex = 1099;


    As already pointed out, this is incorrect. shmat returns a pointer
    to the shared segment. If you are not comfortable with pointers, I
    suggest that you do some experimentation in a simple program
    without shared memory first. Any decent C tutorial should explain
    pointers.

    shmat returns a "generic" pointer (void*) because it has no way of
    knowing what you plan to use the segment for. In your case, since
    you are using it to store an int, you need to store the return
    value of shmat into an "int*", i.e., a pointer to an integer, so:

    int* pTheSharedIndex = shmat( ... )

    Then, to store a value there you would dereference the pointer:

    *pTheSharedIndex = 1099;

    which means "store 1099 in the integer that pTheSharedIndex point
    to".

    MV

    --
    I do not want replies; please follow-up to the group.

  4. Re: Shared Memory...Some Questions.....

    On Mar 21, 7:53 am, Martin Vuille wrote:
    > "Solomon_Man" wrote innews:1174442771.089368.296510@b75g2000hsg.google groups.com:
    >
    > I'm by no means a shared memory expert...
    >
    > > if (pid == 0) /* child process */
    > > {
    > > int indexIdChild = 0;
    > > if((indexIdChild =
    > > shmget(key,sizeof(int),SHM_R|SHM_W))<0)
    > > {
    > > cout<<" CHILD ERROR: indexIdChild "< > > }

    >
    > A few things here...
    >
    > Where does "key" come from? I did not see it declared prior to this
    > point. Same with
    >
    > Attached memory segments are inherited across a fork, so you
    > shouldn't have to repeat the shmget/shmat in the children.
    >
    > You specified IPC_PRIVATE as the key when you first called shmget
    > before the fork. If you want to be able to shmget the same segment
    > in another process, you neet to use the same key in all shmgets and
    > that key cannot be IPC_PRIVATE.
    >
    > > int ctheSharedIndex;
    > > ctheSharedIndex = (int)shmat(indexIdChild,0,0);
    > > */
    > > /* int ctheSharedIndex;
    > > ctheSharedIndex = (int)shmat(indexId,0,0);*/
    > > cout< > > ptheSharedIndex = 1099;

    >
    > As already pointed out, this is incorrect. shmat returns a pointer
    > to the shared segment. If you are not comfortable with pointers, I
    > suggest that you do some experimentation in a simple program
    > without shared memory first. Any decent C tutorial should explain
    > pointers.
    >
    > shmat returns a "generic" pointer (void*) because it has no way of
    > knowing what you plan to use the segment for. In your case, since
    > you are using it to store an int, you need to store the return
    > value of shmat into an "int*", i.e., a pointer to an integer, so:
    >
    > int* pTheSharedIndex = shmat( ... )
    >
    > Then, to store a value there you would dereference the pointer:
    >
    > *pTheSharedIndex = 1099;
    >
    > which means "store 1099 in the integer that pTheSharedIndex point
    > to".
    >
    > MV
    >
    > --
    > I do not want replies; please follow-up to the group.


    All thanks so much for the help. I definetly was flawed on my way of
    thinking for this example.

    I will recode the small test app and try and get it to work from all
    your suggestions.

    After posting this originally, I found a few examples checking the
    return value of shmat ( == (void *)-1) and figured that I definetlly
    had some issue with my original idea. Then I also read on a man page
    at home where the child processes inherits the shared memory after a
    fork. The key issue was a idea I tried after seeing a few examples
    online, I gave up on that and went to IPC_PRIVATE instead of the key.

    Again thank for the help and I will repost with what I come up with
    later tonight.

    Thanks,
    Chris



+ Reply to Thread