Context of the code: Hello, I am trying to create a program that can multiply two 2x2 matrixes using separate processes (child1 and child2). Specifically child1 processes row1 of the resulting matrix and child2 processes row2 of the resulting matrix. This resulting matrix is stored in shared memory.
Problem: shmget() returns -1, and errno is 22 = invalid argument.
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include <stdbool.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "shm_com.h"
//signal handler should be void of return type
void sig_handler(int signo){
printf("Inside handler function\n");
}
int main(){
int PROCESS_COUNT = 0;
bool display = false;
int row, column, limit=2;
int M[2][2] = { {20, 20},
{10, 6}};
int N[2][2] = { {10, 30},
{1, 3}};
int Matrix_Size1=sizeof(M)/sizeof(int);
int Matrix_Size2=sizeof(N)/sizeof(int);
if(Matrix_Size1==Matrix_Size2) printf("Matrixes are the same size\n");
int shmid;
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
//shmid = shmget((key_t)9998, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
shmid = shmget((key_t)9998, sizeof(int * 3 * (2*2)), 0666 | IPC_CREAT);
//Creation of Shared Memory
if (shmid == -1) {
printf("Oh dear, something went wrong with shmget()! %d\n", errno);
exit(EXIT_FAILURE);
}
pid_t pid1,pid2;
pid1 = fork();
PROCESS_COUNT = 1;
if(pid1!=0){
pid2 = fork();
PROCESS_COUNT = 2;
}
//Warning code after this point will be included into child unless in if statement
if ((PROCESS_COUNT == 1 && pid1==0) || (PROCESS_COUNT == 2 && pid2 == 0)){
/* child1 ------------------------------------------------------------*/
if(PROCESS_COUNT == 1){
printf("Child 1 Process: working with Q's 1 row\n");
//sleep(10);
//Get access to shared memory
shared_memory = shmat(shmid, (void *)0, 0);
if (shared_memory == (void *)-1) {
fprintf(stderr, "shmat failed\n");
exit(EXIT_FAILURE);
}
if(display){printf("Child Memory attached at %X\n", (int)shared_memory);}
shared_stuff = (struct shared_use_st *)shared_memory;
for(column=0; column<limit; column++){
for (row=0; row<limit; row++){
shared_stuff->Q_matrix[0][column] += M[0][column]*N[row][column];
printf("check %d ",shared_stuff->Q_matrix[0][column]);
//printf("check Row:%d,Column: %d ",row,column);
}
if(display){printf("Row1_Q_matrix \n");}
printf("\n");
}
//kill(pid1, SIGALRM);
exit(1);
}
/*-------------------------------------------------------------------*/
/* child2 */
else if(PROCESS_COUNT == 2){
printf("Child 2 Process: working with Q's 2 row\n");
//Get access to shared memory
shared_memory = shmat(shmid, (void *)0, 0);
if (shared_memory == (void *)-1) {
fprintf(stderr, "shmat failed\n");
exit(EXIT_FAILURE);
}
if(display){printf("Child Memory attached at %X\n", (int)shared_memory);}
shared_stuff = (struct shared_use_st *)shared_memory;
}
} else {
/* parent ------------------------------------------------------------*/
if(display){printf("Parent pid: %i PROCESS_COUNT: %i \n ", getpid(),PROCESS_COUNT);}
//Get access to shared memory
shared_memory = shmat(shmid, (void *)0, 0);
if (shared_memory == (void *)-1) {
fprintf(stderr, "shmat failed\n");
exit(EXIT_FAILURE);
}
if(display){printf("Parent Memory attached at %X\n", (int)shared_memory);}
shared_stuff = (struct shared_use_st *)shared_memory;
//Write number to shared memory------------------------------------------------*/
//Write and Display M matrix
for (row=0; row<limit; row++)
{
for(column=0; column<limit; column++){
shared_stuff->M_matrix[row][column] = M[row][column];
if(display){printf("%d ", (shared_stuff->M_matrix[row][column]));}
}
if(display){printf("M_matrix \n");}
printf("\n");
}
//Write and Display N matrix
for (row=0; row<limit; row++)
{
for(column=0; column<limit; column++){
shared_stuff->N_matrix[row][column] = N[row][column];
if(display){printf("%d ", (shared_stuff->N_matrix[row][column]));}
}
if(display){printf("N_matrix \n");}
printf("\n");
}
//Write and Display Q matric
printf("Written Matrix\n");
for (row=0; row<limit; row++)
{
for(column=0; column<limit; column++){
shared_stuff->Q_matrix[row][column] = 0;
printf("%d mem:%p \n", (shared_stuff->Q_matrix[row][column]),& (shared_stuff->Q_matrix[row][column]));
}
if(display){printf("Q_matrix");}
printf("\n");
}
wait(NULL);
sleep(10);
printf("Resulting Matrix2\n");
printf("%d Mem: %p \n", (shared_stuff->Q_matrix[0][0]),& shared_stuff->Q_matrix[0][0]);
printf("%d Mem:%p\n", (shared_stuff->Q_matrix[0][1]),& shared_stuff->Q_matrix[0][1]);
printf("%d Mem:%p\n", (shared_stuff->Q_matrix[1][0]),& shared_stuff->Q_matrix[1][0]);
printf("%d Mem:%p\n", (shared_stuff->Q_matrix[1][1]),& shared_stuff->Q_matrix[1][1]);
/*for (row=0; row<limit; row++){
for(column=0; column<limit; column++){
printf("%d mem:%p \n", (shared_stuff->Q_matrix[row][column]),& shared_stuff->Q_matrix[row][column]);
}
if(display){printf("Q_matrix");}
printf("\n");
}*/
exit(EXIT_SUCCESS);
printf("done\n");
}
}
Here is my structure of shared memory:
#define TEXT_SZ 2048
struct shared_use_st {
int M_matrix[2][2];
int N_matrix[2][2];
int Q_matrix[2][2];
};
Can someone explain what I am doing wrong with shmget()?
To note, I have commented out the first try of shmget().
Make some cleanup as you may have an existing segment for the given key but the size does not match. You may have increased the structure meanwhile. Do
ipcrm -M 9998
before launching your program as the manual specifies that EINVAL is raised in the following conditions: