|
#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; |
|
} |
Perfect ! I wish you the best