Solved

shared memory

Posted on 1997-04-25
7
504 Views
Last Modified: 2013-12-26
How do I have to use shared memory (shmget, shmat, shmctl) on an object of a derived class (C++)?

I would like to have two programs that run concurrently, one of them produces data (images), and the other one should display them. My shared memory programs work fine on "normal" variables (e.g. int), but not on class objects.

Following is a code fragment from one of the two programs. The shared memory is allocated and attached in the same way in the other program.

*****************

1   key_t         image_key = 5;
2   int           image_shmid;
3   ilMemoryImg*  image;   // ilMemoryImg is a derived class                      

   /* Allocate shared memory and attach variables */

4   image_shmid = shmget(image_key, sizeof(ilMemoryImg),
5                        SHM_W | SHM_R | IPC_CREAT);
6   if (image_shmid == -1) {
7     perror("shmget image");
8     exit(0);
9   }
10  image = (ilMemoryImg*) shmat(image_shmid, NIL, NIL);
11  if ((long) image == -1){
12    perror("shmat image");
13    exit(0);
14  }

...

  /* Create image */

15  image_size = raw_pallet_image->getSize();
16  image = new ilMemoryImg(image_size, ilUChar,
17                          ilInterleaved);
18  image->setCoordSpace(ilUpperLeftOrigin);
19  image->setColorModel(ilMinBlack);

****************************

Thanks for any hints!
Please reply also by email to allegro@imt.dmt.epfl.ch


0
Comment
Question by:allegro
  • 4
  • 3
7 Comments
 
LVL 2

Accepted Solution

by:
mlev earned 100 total points
Comment Utility
Call the constructor explicitly:

Instead of
      image = new ilMemoryImg(whatever)
use
      image = (ilMemoryImg*)shmat(.....);
      image->ilMemoryImg(whatever);

Good luck
0
 

Author Comment

by:allegro
Comment Utility
Edited text of question
0
 

Author Comment

by:allegro
Comment Utility
Hello mlev,

thanks for your quick response. I don't get it, however:
Since image is declared as a pointer to ilMemoryImg (line 3 modif. question), don't I have to create it with NEW explicitely (line 16/17)? If not, how can I create it? In line 10 the image is already attached, just as you proposed. Now where does what need to go exactely (creating image, shmget, shmat)? I suppose I don't need to attach it twice?

Thanks in advance

0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 2

Expert Comment

by:mlev
Comment Utility
No, you don't need to attach it twice. I just wasn't sure the lines were from the same process.
After you get an address from shmat(), your problem can be described in the following way:
Create a class object in a given memory location.

When you create a class object with `new', it allocates the memory alone. In fact, `new' first allocates memory and then invokes the class constructor.
The expression
      new Class(Arguments)
can be replaced with
      ((Class*)malloc(sizeof(Class)))->Class(Arguments)
(not strictly speaking, since this doesn't check for errors)
Since you do not want to allocate memory for the object, but use the address you received from shmat(), I suggested that you just call the constructor.
By the way, I hope you made sure that all the data you want to be shared is contained by value in the class structure, not by reference.
0
 

Author Comment

by:allegro
Comment Utility
ok, guess we're coming closer to the problem:

I have a program "process_image" where I create and process the image. The code I provided is from this program. Another program called "display_image" takes the shared image for display. I understand that I don't need to allocate memory within "display_image", because there I only read (i.e. display) the image which does already exist (I check for that). However, within "process_image" I need to allocate the memory, because I will process (i.e. modify) the image before I can display it.

As for data being contained in the class structure by value, I am not sure what you mean (I am not really in CS), moreoer I have not written the classes myself, the corresponding h-file is below (sorry this gets kind of long).

Did I misunderstand the possibilities of shared memory? (As I wrote in the question, I would like to have "process_image" and "display_image" running in 'parallel', this is to prevent to have to include all my image processing in a loop for displaying.) If not, how and where do I need to create the image in "process_image"?


imtsg8 8% more /usr/include/il/ilMemoryImg.h
#if 0

    Copyright (c) 1991 SGI   All Rights Reserved
    THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SGI
    The copyright notice above does not evidence any
    actual or intended publication of such source code,
    and is an unpublished work by Silicon Graphics, Inc.
    This material contains CONFIDENTIAL INFORMATION that
    is the property of Silicon Graphics, Inc. Any use,
    duplication or disclosure not specifically authorized
    by Silicon Graphics is strictly prohibited.
   
    RESTRICTED RIGHTS LEGEND:
   
    Use, duplication or disclosure by the Government is
    subject to restrictions as set forth in subdivision
    (c)(1)(ii) of the Rights in Technical Data and Computer
    Software clause at DFARS 52.227-7013, and/or in similar
    or successor clauses in the FAR, DOD or NASA FAR
    Supplement.  Unpublished- rights reserved under the
    Copyright Laws of the United States.  Contractor is
    SILICON GRAPHICS, INC., 2011 N. Shoreline Blvd.,
    Mountain View, CA 94039-7311

#endif
/*
    The memory image class defines a simple memory resident image.
    This class can be used as a simple means of importing or exporting data
    outside the IL.
*/

#ifndef _ilMemoryImg_h_
#define _ilMemoryImg_h_

#include <il/ilImage.h>

class ilMemoryImg : public ilImage {
public:
    ilDeclareDerivedClass

    // data access methods
    //
    ilStatus getSubTile3D(int x, int y, int z, int nx, int ny, int nz,
                          void* data, int dx, int dy, int dz, int dnx,
                          int dny, int dnz, const ilConfig* config=NULL);
    ilStatus setSubTile3D(int x, int y, int z, int nx, int ny, int nz,
                          void* data, int dx, int dy, int dz, int dnx,
                          int dny, int dnz, const ilConfig* config=NULL);
    ilStatus copyTileCfg(int x, int y, int z, int nx, int ny, int nz,
                        ilImage* other, int ox, int oy, int oz,
                        const ilConfig* cfg=NULL, int from=1);
    ilStatus fillTile3D(int x, int y, int z, int nx, int ny, int nz,
                        void* data, const ilConfig* config=NULL,
                        const ilTile* fillMask=NULL);
   
    ilStatus lockPageSet(ilLockRequest* set, int mode=ilLMread, int count=1);
    void unlockPageSet(ilLockRequest* set, int count=1);


    ~ilMemoryImg();

    // external api: begin
    // external api: name=ilMemoryImgNull
    ilMemoryImg();
    ilMemoryImg(const ilSize& size, ilType type, ilOrder order);
    // external api: name=ilMemoryImgData
    ilMemoryImg(void* data, const ilSize& size, ilType type, ilOrder order);
    // external api: name=ilMemoryImgImg
    ilMemoryImg(ilImage* img, int autoSyncEnable = TRUE);
   
    void* getDataPtr() { resetCheck(); return imageData;}
    void setDataPtr(void* data);
    void markDirty() { setAltered(ilLPonlyChildren); }
   
    void setAutoSync(int enable);       // If TRUE then sync during reset
    void sync();                        // Sync params/data to input image
   
    // external api: end

protected:

    void reset();

private:

    void init(const ilSize& sz, ilType type, ilOrder ord);
    void syncData();
   
    void*       imageData;
    ilPage*     page;
    int         allocated;      // number of bytes allocated (0 ==> user allocated)
    int         autoSync;       // If TRUE then sync data from image during reset
    ilImage*    inImg;          // Input image (optional)

};
#endif


0
 
LVL 2

Expert Comment

by:mlev
Comment Utility
If you use `new', it does allocate space for you, but it allocates it in private memory. There is no way in Unix, as far as I know, to take a piece of private memory and make it shared memory. So instead, you take a piece of shared memory and use it for storing your object. You can think of shmget() + shmat() as of your memory allocator, except it actually does allocation only once, and then keeps returning the same address.

Now for the header - it's just what I was afraid of.
You see, it contains pointers to actual data, e.g.,
void *imageData;
The data itself is stored somewhere else, outside the class.
Even if you put the object in shared memory, the second process
will be able to see the value of the pointer, i.e., the address,
but it won't be able to see the data (which will be stored somewhere in the first process' private memory).
Sorry to tell you this, but if you are determined to get this done, the classes will need a major rewrite.

0
 

Author Comment

by:allegro
Comment Utility
Well, so I can't realize this because the classes are provided by an application program and I cannot change them... :(

Thanks anyways for your help, your comments were very useful!
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now