Tech Today

Linux: Process Memory Sharing in [C]

Posted on: May 15, 2009

So, today I am working on understanding how processes communicate in the Linux OS. This code example is written in C and compiled in Ubuntu 9.04 using the Jaunty Jackalope Kernel version 2.6.28-11.

This code specifically prints out the Fibonacci sequence.

The parent process creates and attaches a shared memory segment, forks a child process (remember the child process shares the resources of the parent) , waits for the child to finish, prints out the contents of the shared memory, and finally detaches and removes the shared memory segment.

The child process runs through the Fibonacci algorithm, inserts the resultant into the next available space in shared memory and prints out the resultant to standard output.

This example accepts input from the command line with basic error checking. You know, make sure two args have been provided, they are between the min and max limits of the program; the BASICS.

CODE:

#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define MAX_SEQUENCE 10 // Max values to store in shared memory
#define MIN_SEQUENCE 2  // Min value the user can enter

//shared memory:
// 1) holds an array of numbers
// 2) holds how many numbers are in the array
typedef struct {
int fib_seq[MAX_SEQUENCE];
int sequence_size;
} shared_data;

//MAIN function
int main(int argc, char *argv[]) {

pid_t pid;    //process ID
int segment_id; //Shared Memory ID
shared_data *mem; //Shared Memory Pointer

//check to validate atleast two arguments
if(argc != 2) {
printf(“USAGE ERROR: [0-9]\n”);
exit(0);
}

//validate the input is not larger then the MAX
if(atoi(argv[1]) > MAX_SEQUENCE) {
printf(“Max Input Size: %d\n”, MAX_SEQUENCE);
exit(0);
}

//validate the input is not smaller then the MIN
if(atoi(argv[1]) < MIN_SEQUENCE) {
printf(“Min Input Size: %d\n”, MIN_SEQUENCE);
exit(0);
}

// 1) create a new shared memory location ‘IPC_PRIVATE’
// 2) the size of our shared memory structure ‘sizeof(shared_data)’
// 3) Set Modes S_IRUSR and S_IWUSR so the owner can read and write to the shared memory ‘S_IRUSR|S_IWUSR’
segment_id = shmget(IPC_PRIVATE, sizeof(shared_data), S_IRUSR|S_IWUSR);

//attach the shared memory and get the pointer to the beginning location in memory
mem = (shared_data *) shmat(segment_id,NULL,0);

//set the size of the sequence to the argument that was passed in via command line
mem->sequence_size = atoi(argv[1]);

// fork a child process
pid = fork();

if(pid < 0) { /* error occured */
fprintf(stderr, “Fork Failed\n”);
return 1;
}
else if(pid == 0) { /* child process */
int counter = 0;
printf(“Child Fibonacci Sequence: “);

while(counter < mem->sequence_size) {
if(counter == 0){
//FIB of zero is always zero
mem->fib_seq[counter] = 0;
}
else if(counter == 1){
//FIB of one is always one
mem->fib_seq[counter] = 1;
}
else {
//The Fibonacci Sequence formula ‘R = fib(n-1) + fib(n-2)’
//The first two numbers in the sequence are always 0 and 1.
//To get a value in the sequence you will want to take the previous
//two numbers and add them together. For example:
// b + a = c
// [fib(d-1) = c] + [fib(d-2) = b] = R
// fib(0) = 0
// fib(1) = 1
// fib(2): 1 + 0 = 1
// fib(3): 1 + 1 = 2
// fib(4): 2 + 1 = 3
// fib(5): 3 + 2 = 5
// The next Fibonacci number in the sequence will be ‘8’
mem->fib_seq[counter] = mem->fib_seq[counter – 1] + mem->fib_seq[counter – 2];
}
printf(“%d “, mem->fib_seq[(counter)]);
counter++;
}
}
else { /* parent process */

/* parent will wait for the child process to complete */
wait(NULL);

//Print out shared memory
int count = 0;
printf(“\nParent Fibonacci Sequence: “);
while(count < mem->sequence_size){
printf(“%d “, mem->fib_seq[count]);
count++;
}

//detach shared memory
shmdt(mem);
//remove shared memory segment
shmctl(segment_id,IPC_RMID,NULL);
printf(“\nComplete\n”);
}

return 0;
}

output:


lee@isis:~$ ./a.out 0
Min Input Size: 2
lee@isis:~$ ./a.out 1
Min Input Size: 2
lee@isis:~$ ./a.out 2
Child Fibonacci Sequence: 0 1
Parent Fibonacci Sequence: 0 1
Complete
lee@isis:~$ ./a.out 3
Child Fibonacci Sequence: 0 1 1
Parent Fibonacci Sequence: 0 1 1
Complete
lee@isis:~$ ./a.out 4
Child Fibonacci Sequence: 0 1 1 2
Parent Fibonacci Sequence: 0 1 1 2
Complete
lee@isis:~$ ./a.out 5
Child Fibonacci Sequence: 0 1 1 2 3
Parent Fibonacci Sequence: 0 1 1 2 3
Complete

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: