Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does one keep an int and an array in shared memory in C?

I'm attempting to write a program in which children processes communicate with each other on Linux.

These processes are all created from the same program and as such they share code.

I need them to have access to two integer variables as well as an integer array.

I have no idea how shared memory works and every resource I've searched has done nothing but confuse me.

Any help would be greatly appreciated!

Edit: Here is an example of some code I've written so far just to share one int but it's probably wrong.

int segmentId;  
int sharedInt;  
const int shareSize = sizeof(int);  
/* Allocate shared memory segment */  
segmentId = shmget(IPC_PRIVATE, shareSize, S_IRUSR | S_IWUSR);  

/* attach the shared memory segment */    
sharedInt = (int) shmat(segmentId, NULL, 0);  

/* Rest of code will go here */  

/* detach shared memory segment */  
shmdt(sharedInt);  
/* remove shared memory segment */  
shmctl(segmentId, IPC_RMID, NULL);
like image 643
Josh Avatar asked Nov 04 '09 02:11

Josh


2 Answers

You are going to need to increase the size of your shared memory. How big an array do you need? Whatever value it is, you're going to need to select it before creating the shared memory segment - dynamic memory isn't going to work too well here.

When you attach to shared memory, you get a pointer to the start address. It will be sufficiently well aligned to be used for any purpose. So, you can create pointers to your two variables and array along these lines (cribbing some of the skeleton from your code example) - note the use of pointers to access the shared memory:

enum { ARRAY_SIZE = 1024 * 1024 };
int segmentId;  
int *sharedInt1;
int *sharedInt2;
int *sharedArry;

const int shareSize = sizeof(int) * (2 + ARRAY_SIZE);  
/* Allocate shared memory segment */  
segmentId = shmget(IPC_PRIVATE, shareSize, S_IRUSR | S_IWUSR);  

/* attach the shared memory segment */    
sharedInt1 = (int *) shmat(segmentId, NULL, 0);
sharedInt2 = sharedInt1 + 1;
sharedArry = sharedInt1 + 2;

/* Rest of code will go here */
...fork your child processes...
...the children can use the three pointers to shared memory...
...worry about synchronization...
...you may need to use semaphores too - but they *are* complex...
...Note that pthreads and mutexes are no help with independent processes...  

/* detach shared memory segment */  
shmdt(sharedInt1);  
/* remove shared memory segment */  
shmctl(segmentId, IPC_RMID, NULL);
like image 186
Jonathan Leffler Avatar answered Oct 14 '22 02:10

Jonathan Leffler


From your comment it seems you're using IPC_PRIVATE, and that definitely looks wrong ("private" kinds of suggest it's not meant for sharing, no?-). Try something like:

#include <sys/ipc.h>
#include <sys/shm.h>

...

int segid = shmget((key_t)0x0BADDOOD, shareSize, IPC_CREAT);
if (segid < 0) { /* insert error processing here! */ }
int *p = (int*) shmat(segid, 0, 0);
if (!p) { /* insert error processing here! */ }
like image 44
Alex Martelli Avatar answered Oct 14 '22 01:10

Alex Martelli