6

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);
2
  • Note this question from yesterday: stackoverflow.com/questions/1664519/… (same general subject, though you have selected Sys V IPC). Commented Nov 4, 2009 at 3:09
  • Outside of IPC_PRIVATE, if you use a different key, what does it do or not do? Commented Nov 4, 2009 at 3:15

4 Answers 4

8

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);
Sign up to request clarification or add additional context in comments.

Comments

1

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! */ }

5 Comments

That looks interesting. I'm not the greatest when it comes to C so will p be the int array in this case? I'm also curious about that hex value you have in the shmget.
IPC_PRIVATE works if the parent creates the shared memory and then forks the children who are going to share it.
@Josh: you need a 32-bit value as the key for the shared memory. You can either use ftok() to create one, or choose a fixed name. No Bad Dood is as good a name as any for a piece of shared memory as any other. 0xDEADBEEF is another well known value. But IPC_PRIVATE is good too - as long as the parent process creates and attaches the shared memory before forking.
Oh! I didn't even get that reference. Pretty sweet haha
@Jonathan, yep -- if you're forking (and not exec'ing: per linux.die.net/man/2/shmget , exec detaches all shm segments) IPC_PRIVATE is fine. But fork-w/o-exec is a pretty rare case in my experience.
0

This guide looks useful: http://www.cs.cf.ac.uk/Dave/C/node27.html. It includes some example programs.

There are also Linux man pages online.

4 Comments

Thanks but unfortunately that's one of those pages that thoroughly confused me.
Have you tried copy and pasting the example code there and compiling it? If you can get that to compile you are probably half way there to understanding it.
My problem with that example is that it seems to be different programs talking in a client-server manner. I hadn't clarified what I need at the time in my original question but in my code I will be creating multiple processes from the same program and need them to communicate.
I think you need to break your problem down in to steps and then try to solve them one at a time.
0

Shared memory is just a segment of memory allocated by one process, with a unique id, and the other process will also make the allocation, with the same id, and the size of the memory is the sizeof the structure that you are using, so you would have a structure with 2 integers and an integer array.

Now they both have a pointer to the same memory, so the writes of one will overwrite whatever else was there, and the other has immediate access to it.

3 Comments

@Josh no, comment formatting sucks moldy rocks -- but then you're supposed to edit your question to clarify it, instead of commenting, so you can format your code prettily in an edit of your answer, and delete these comments!
I'd recommend you add clarification to your original question.
@Josh - you may want to look at this tutorial: ecst.csuchico.edu/~beej/guide/ipc/shmem.html, as he also shows how to use ftok to create a key for the call.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.