Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

shared memory

Posted on 1997-04-25
7
Medium Priority
?
581 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
7 Comments
 
LVL 2

Accepted Solution

by:
mlev earned 200 total points
ID: 1292657
Call the constructor explicitly:

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

Good luck
0
 

Author Comment

by:allegro
ID: 1292658
Edited text of question
0
 

Author Comment

by:allegro
ID: 1292659
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 2

Expert Comment

by:mlev
ID: 1292660
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
ID: 1292661
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
ID: 1292662
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
ID: 1292663
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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
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.
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…

604 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