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;
    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 = fork();
    }


    //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
    {

        wait(NULL);

        int i;
        int j;

        //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

Dani AI

Generated

Common issues observed in the thread (notes for , building on ): dereferencing *partition before calling shmat() is undefined and will crash; the child processes in the posted code write into stack/local arrays, so their results are not visible to the parent (fork gives each process its own address space — copy-on-write); calling fork() repeatedly without stopping children will create more processes than intended; and a single wait(NULL) only reaps one child. (man7.org)

A simple, reliable pattern:

  • Put the result matrix (and, if desired, A and B) inside a single shared segment created with shmget()/shmat() and only initialize the shared memory after shmat() returns.
  • Spawn exactly N workers with a loop that stops child processes from forking further; give each child a worker id and compute its row range deterministically (avoid a shared counter unless protected). Example fork pattern and row math:
/* spawn N workers; child sets worker_id and breaks so it does not fork again */
int worker_id = -1;
for (int i = 0; i < N; ++i) {
    pid_t pid = fork();
    if (pid < 0) { perror("fork"); exit(1); }
    if (pid == 0) { worker_id = i; break; } /* child */
}

/* per-worker row range with balanced remainder */
int base = DIM / N;
int extra = DIM % N;
int start = worker_id * base + (worker_id < extra ? worker_id : extra);
int rows = base + (worker_id < extra ? 1 : 0);
int end = start + rows;

/* compute C[start..end-1] in shared memory */

After creating all children the parent should wait for each child (call wait()/waitpid() N times) and then detach/remove the shared segment with shmdt() and shmctl(..., IPC_RMID, ...). Using the shared-memory layout as a struct (partition/counters + A + B + C) keeps offsets clear. For details on the system calls used see the manual pages. (man7.org)

Extra tips: if multiple workers will claim work from a shared counter, protect it with a proper interprocess semaphore (POSIX or SysV) or give each worker a fixed index to avoid synchronization entirely; for very large matrices prefer mmap(MAP_SHARED) or heap allocation mapped into shared memory to avoid stack overflow. (man7.org)

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;
    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 = fork();
    }


    //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
    {

        wait(NULL);

        int i;
        int j;

        //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

First step check this
#
for(i = 0; i < NUM_OF_FORK_CALLS; i++)
#
{
#
pid = fork();
#
}

This will create more than 3 processes since after each child is created, both parent and child will call fork

modify the code to call fork only if pid != 0

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.