Jump to content

Need some help with shared memory and fork system call

- - - - -

  • Please log in to reply
1 reply to this topic

#1
Uni616

Uni616

    Newbie

  • Members
  • Pip
  • 2 posts
Hello, I'm trying to make a program that will multiply 2 matrices using shmget() and fork(). For example, I would need to multiply a 64 x 64 matrix using 4 processes or 16 processes, and the multi-processes will be created using fork. Each process will calculate a partition of the final Matrix

Now, I'm not sure whether I should write all the matrices to the shared memory or just a single integer to keep track of what partition to calculate. I'm also not sure if I'm using fork correctly, as my print commands print out twice each instead of once.



#include <stdio.h>

#include <sys/shm.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <unistd.h>



#define DIM 4

#define NUM_OF_FORK_CALLS 2

#define NUM_OF_PROC 4


int main()

{

    pid_t pid[NUM_OF_PROC];

    int segment_id;

    int *partition;

    *partition = 0;

    int i;

    int j;

    int matrixA[DIM][DIM];

    int matrixB[DIM][DIM];

    int matrixC[DIM][DIM];


    //allocating a shared memory segment

    segment_id = shmget(IPC_PRIVATE, sizeof(int)*(DIM*DIM)*3, IPC_CREAT|0666);


    //attach the shared memory segment to the partition variable

    partition = (int *) shmat(segment_id, NULL,0);


    //fill the matrices

    for(i = 0; i < DIM; i++)

    {

	for(j = 0; j < DIM; j++)

	{

		matrixA[i][j] = i + j;

		matrixB[i][j] = i + 3;

	}

    }


    for(i = 0; i < NUM_OF_FORK_CALLS; i++)

    {

   	pid_t id = fork();

        if (id == 0) break;

        pid[i] = id;

    }



    //error occurred

    if(pid < 0)

    {

        fprintf(stderr, "Fork Failed");

        return 1;

    }


    //child process

    else if(pid==0)

    {


        int start = (*partition * DIM)/NUM_OF_PROC;

        /*The start position will tell which row to start calculating */


        int end = ((*partition+1) * DIM)/NUM_OF_PROC;

        /*The end position wil tell which row to stop calculating*/


        int i;

        int j;

        int k;


         //These for loops will calculate a partition of C

        for(i = start; i<end; i++)

        {

            for(j = 0; j < DIM; j++)

            {

                matrixC[i][j] = 0;


                for(k = 0; k < DIM; k++)

                {

                     matrixC[i][j] += matrixA[i][k] * matrixB[k][j];

                }

             }

        }


    }


    //parent process

    else

    {

        int i;

        int j;


        for(i = 0; i < NUM_OF_FORK_CALLS; i ++)

        {

            waitpid(pid[i],NULL,0);

        }

        


        


        //print matrix A

        for(i = 0; i < DIM; i++)

        {

            for(j = 0; j<DIM; j++) 

            {

                printf("%d ",matrixA[i][j]);  

            }


            printf("\n");  

        }


        printf("-----------\n\n");


        //print matrix B

        for(i = 0; i < DIM; i++)

        {

            for(j = 0; j<DIM; j++)  

            {

                printf("%d ",matrixB[i][j]);  

            }


            printf("\n");  

        }


         printf("-----------\n\n");


        //print matrix C

        for(i = 0; i < DIM; i++)

        {

            for(j = 0; j<DIM; j++) 

            {

                printf("%d ",matrixC[i][j]);  

            }


            printf("\n"); 

        }

         printf("-----------\n\n");


    }


    return 0;

}



Any help would be appreciated, thanks in advance

#2
bobdark

bobdark

    Programmer

  • Members
  • PipPipPipPip
  • 164 posts
if(pid < 0)
    {
        fprintf(stderr, "Fork Failed");
        return 1;
    }

    //child process
    else if(pid==0)
Ahh did you mean maybe id instead of pid?

Another thing that bothered me, (maybe its just me being stupid of course) is that I didn't really get where do you determine a different chunk of information for each process to work with. It seems to me that the processes do the same thing.

I probably would do it somewhat like this:
1)Father process allocates needed memory and spawns children processes
2)Children go to sleep right after they are created, in order to let father finish the initialization stage.
3)Father decides what each process should do and wakes the appropriate processes
4)once a proccess awakes (or if its the father, finishes the init. stage) it begins its job.
5)Once a process finishes it's job, if its the father, it waits for children otherwise it can finish.
6)Father prints the matrix

Basically, I presented a scenario of Master and a pool of Worker processes. The master makes the initialization and dispatches jobs to workers. Each worker waits for a job and usually notifies the master when it finishes it. In this case children can just quit. Master waits for all the workes to finish and does the remaining work ( cleanup, presentation to user,...).




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users