Skip to content

Instantly share code, notes, and snippets.

@wtneal
Created September 25, 2014 01:00
Show Gist options
  • Save wtneal/d00b72609fd74dff40e6 to your computer and use it in GitHub Desktop.
Save wtneal/d00b72609fd74dff40e6 to your computer and use it in GitHub Desktop.
#include <sys/shm.h>
#include <sys/wait.h>
#include <malloc.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <error.h>
#include <math.h>
/*
* This code is not complete.
* It is only a starting point, or for reference.
* It is missing several parts
* E.g. time-stamping, multiple matrices
*/
#define N 4
typedef struct matrixstruct {
int C[N][N];
} matstr;
matstr *Cms; /* pointer to output matrix C */
int Cid; /* segment id for output matrix C */
int base_pid, status, pid;
int main()
{
int i,j;
int rank, chunk, u, t;
// Get the size of the work that each process will have to do.
chunk = N / sqrt(4);
/*
*
* STEP 1: create the shared segment
*/
if ((Cid = shmget(IPC_PRIVATE, sizeof(matstr), IPC_CREAT | 0666)) < 0)
{
perror("smget returned -1\n");
error(-1, errno, " ");
exit(-1);
}
printf("Allocated %d, at id %d\n", (int) sizeof(matstr), Cid);
/*
*
* STEP 2: fork the children processes
*/
base_pid = getpid();
for(i=1; i<N; i++) {
if (getpid()==base_pid)
pid = fork();
else
break;
}
/*
*
* STEP 3: each child process attaches the segment
*/
if ((Cms = (matstr *) shmat(Cid, NULL, 0)) == (matstr *) -1){
perror("Process shmat returned NULL\n");
error(-1, errno, " ");
}
else
printf("Process %d attached the segment %d\n", getpid(), Cid);
/*
*
*
*
* STEP 4: use the shared segment
*
*
*
*/
// Get the process id
rank = getpid()-base_pid;
// Calculate the offsets for the result matrix
u = (rank % (N/chunk)) * chunk;
t = floor((rank * chunk) / N) * chunk;
// Loop over the matrix chunk for this process
for (i=u;i<(u+chunk);i++) {
for (j=t;j<(t+chunk);j++) {
Cms->C[i][j] = rank;
}
}
/*
*
* STEP 5: each child process detaches the segment
*/
if (shmdt(Cms) == -1){
perror("shmdt returned -1\n");
error(-1, errno, " ");
}else
printf("Process %d detached the segment %d\n", getpid(), Cid);
/*
*
* STEP 6: each child process exits and the parent joins
*/
if (getpid()==base_pid)
for(i=1; i<N; i++) {
wait(NULL);
}
else
exit(0);
// Print out the matrix
Cms = (matstr *) shmat(Cid, NULL, 0);
for (i=0;i<N;i++) {
printf("[");
for (j=0;j<N;j++) {
printf("%d, ", Cms->C[i][j]);
}
printf("]\n");
}
printf("\n\n");
/*
*
* STEP 7: base process deletes the segment
*/
if (shmctl(Cid,IPC_RMID,NULL) == -1){
perror("shmctl returned -1\n");
error(-1, errno, " ");
}
return 0;
}
@kabhilan41
Copy link

U r a lifesaver man

@eugeneai
Copy link

Thanks. It was used within student's lection.

@totohero
Copy link

I'm curious what will happen if fork AFTER shmat. Will the same virtual address acquired by shmat remain vaild shared memory between the processes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment