views:

580

answers:

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);
A: 

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.

Kinopiko
Thanks but unfortunately that's one of those pages that thoroughly confused me.
Josh
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.
Kinopiko
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.
Josh
I think you need to break your problem down in to steps and then try to solve them one at a time.
Kinopiko
A: 

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.

So what part is getting you confused?

Do you have some code of what you are trying to do?

James Black
@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!
Alex Martelli
I'd recommend you add clarification to your original question.
Carl Norum
@Josh - you may want to look at this tutorial: http://www.ecst.csuchico.edu/~beej/guide/ipc/shmem.html, as he also shows how to use ftok to create a key for the call.
James Black
That guide looks pretty good. Thanks for all the help!
Josh
A: 

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! */ }
Alex Martelli
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.
Josh
IPC_PRIVATE works if the parent creates the shared memory and then forks the children who are going to share it.
Jonathan Leffler
@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.
Jonathan Leffler
Oh! I didn't even get that reference. Pretty sweet haha
Josh
@Jonathan, yep -- if you're forking (and not exec'ing: per http://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.
Alex Martelli
+3  A: 

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);
Jonathan Leffler
This looks pretty great. Thanks so much!
Josh
A: 

Stop being Lazy, i have the same project. Do some research.

justridelow
A: 

Just playing, its simple if you break it down by parts, u should read the advance unix programming guide. that book really help.

justridelow