passing values from child to parent process using a shared file - c

the following c program takes inputs for a 2D - array, and then takes a value n and multiplies every element by n. the child process iterates through the matrix, opens the file named sharedfile and then writes the value into the file. the parent process then open sharedfile and reads the values and prints them. I know there are probably better ways to accomplish this but this is the method we are learning currently.
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv[]){
int row = 0;
int column = 0;
if(argc > 2){
row = atoi(argv[1]);
column = atoi(argv[2]);
}
int *A = (int *) malloc((row * column) * sizeof(int));
int i, j;
printf("Enter the matrix elements:\n");
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
printf("A[%d,%d] = ", i, j);
scanf("%d", A + i * column + j); //matrix elements is stored in row-wise
}
printf("\n");
}
enter n
int n = 0;
printf("Enter a number:");
scanf("%d", &n);
child process code:
char sharedfile[] = "child_result.txt";
for(int i = 0; i < row; ++i){
pid_t pid = fork();
if (pid == -1){//not able to create child
printf("parent PID %d => \n", getpid());
int Y[1000];
for (j = 0; j < column; j++) {
Y[j] = n * (*(A + i * column + j));
int fd = open(sharedfile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
int byte_write = write(fd,Y,sizeof(Y));
printf("%d * A[%d,%d] = %d\n", n, i, j,byte_write);
close(fd);
exit(0);
}
}
else if (pid == 0) {//child
printf("child%d PID: %d \n", i, getpid());
int Y[1000];
for (j = 0; j < column; j++) {
Y[j] = n * (*(A + i * column + j));
int fd = open(sharedfile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
int byte_write = write(fd,Y,sizeof(Y));
printf("%d * A[%d,%d] = %d\n", n, i, j,byte_write);
close(fd);
exit(0);
}
}
parent process code:
int child_exit;
wait(&child_exit);
printf("Final matrix elements:\n");
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
int fd = open(sharedfile,O_RDONLY);
int Y[1000];
int byte_read = read(fd,Y,sizeof(Y));
printf("A[%d,%d] = %d\n", i, j, byte_read);
close(fd);
}
printf("\n");
}
exit(0);
}
}
output if I enter n = 2 for a 2d array = {{1,2,3},{4,5,6}}. the result is 4 no matter what input values I enter, what's going wrong here?
Enter a number:2
child0 PID: 31930
2 * A[0,0] = 4
Final matrix elements:
A[0,0] = 4
A[0,1] = 4
A[0,2] = 4
A[1,0] = 4
A[1,1] = 4
A[1,2] = 4

Related

How to append elements to an array in a program in C?

I want the user to input values of elements to an array of 10 ints. Then I want to print out all the indexes of the values of the elements which when divided by 5 give 0.
I've tried doing it like this, but it's not working. How do I append the i's into an array?
#include <stdio.h>
#define N 10
int main()
{
int a[10];
int i;
int index[10] = {};
printf("Input %d values into the array:\n", N);
for (i = 0; i < N; i++){
scanf("%d", &a[i]);
if (a[i] % 5 == 0){
index[10] += i;
}
}
printf("%d", index);
return 0;
}
You can create a new index for the second array and solve the problem. But is better to make it in different loops.
#include <stdio.h>
#define N 10
int main()
{
int a[N];
int index[N] = {};
//o will be the index for index array
int o = 0;
printf("Input %d values into the array:\n", N);
for (int i = 0; i < N; i++){
scanf("%d", &a[i]);
if (a[i] % 5 == 0){
index[o] = i;
o++;
}
}
for(int i = 0; i<o;i++){
printf("%i",index[i]);
}
return 0;
}
Your last comment clarified the intention of your code so here is how solve it directly without the restoring to dynamic memory allocation:
#include <stdio.h>
#define N 10
int main(void) {
int result[N];
int n = 0;
for (int i = 0; i < N; i++){
int d;
if(scanf("%d", &d) != 1) {
printf("scanf failed\n");
return 1;
}
if (!(d % 5)) {
result[n++] = i;
}
}
for(int i = 0; i < n; i++) {
printf("%d%s", result[i], i + 1 < n ? "," : "\n");
}
}
and example run:
echo "1 2 3 4 5 6 7 8 9 10" | ./a.out
4,9

Going over a matrix while multi-threading

I need to create a program that gets a dynamic matrix and changes it to one dimension, for example 4x4 matrix will give 16 arrays length, where each index has a odd or even number, matching the index itself. The threads needs to go over the matrix at the same time and copy the odd and even numbers to the correct places in the array. The main thread needs to wait for the rest of them to finish before printing the array and every value with its respective thread. It should come out like this
We managed to fix the segmentation fault that kept happening, but now we need to set it so that each thread runs right after the other but instead each thread runs 4 times and then it switches to a different one. How can I change it so it'll run as asked?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <pthread.h>
#include <math.h>
#define CORE 4
int N;
int odd = 1;
int even = 0;
typedef struct my_thread {
int** matrix;
int* resArray;
int threadId;
int strart_raw;
int strart_cal;
int end_raw;
int end_cal;
int counter;
} my_thread;
void* createArray(struct my_thread* thread);
void main() {
pthread_t th[CORE];
int s_r = 0, s_c, e_r, e_c;
int i, j, lines, columns, * intMatrix;
printf("Type the N for the N*N matrix:\t");
scanf("%d", &N);
int size = N * N;
int result_Array[N * N];
int retcode;
int interval = size / CORE;
int matrix_build_counter = 1;
intMatrix = (int*)malloc(N * N * sizeof(int));
for (i = 0; i < N; ++i)
{
for (j = 0; j < N; ++j)
{
intMatrix[i * N + j] = matrix_build_counter;
matrix_build_counter++;
}
}
printf("The matrix:\n");
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
printf("%d ", intMatrix[i * N + j]);
}
printf("\n");
}
struct my_thread thred_obj_array[CORE];
for (int i = 0; i < CORE; i++) {
thred_obj_array[i].matrix = &intMatrix;
thred_obj_array[i].resArray = result_Array;
thred_obj_array[i].threadId = i;
thred_obj_array[i].strart_raw = (int)((i * N) / CORE);
thred_obj_array[i].end_raw = (int)(((interval * (i + 1)) / N));
thred_obj_array[i].strart_cal = ((interval * i)) % N;
thred_obj_array[i].end_cal = ((interval) * (i + 1));
thred_obj_array[i].counter = (int)floor((interval)*i);
}
for (int i = 0; i < CORE; i++) {
retcode = pthread_create(&th[i], NULL, createArray, &thred_obj_array[i]);
if (retcode != 0) {
printf("Create thread failed with error %d\n", retcode);
}
}
printf("done");
for (int i = 0; i < CORE; i++) {
pthread_join(th[i], NULL);
}
printf("the result array is: ");
for (int i = 0; i < N * N; i++) {
printf("%d ", result_Array[i]);
}
}
void* createArray(struct my_thread* thread) {
int j;
for (int i = thread->strart_raw; i < N; i = i * sizeof(int) * N) {
for (j = thread->strart_cal; j < N; j++) {
printf("I am thread: %d And my value is: %d , (%d,%d)\n", thread->threadId, (*thread->matrix + i * N)[j], i, j);
if (((*thread->matrix + i * N)[j]) % 2 == 0) {
thread->resArray[even] = (*thread->matrix + i * N)[j];
even += 2;
printf("-----%d ---even---\n", even);
}
else {
thread->resArray[odd] = (*thread->matrix + i * N)[j];
odd += 2;
printf("---%d ---odd--\n", odd);
}
(thread->counter)++;
if (thread->counter == thread->end_cal) {
return;
}
}
thread->strart_cal = 0;
}
}

Multiplication of square matrix with fork (); in C

I made in C a program in Linux of multiplication of matrices of order 1000 A and B. And now I have to add processes!
And now I have to add 4 processes in the multiplication that will result in array C.
1 process for calculating from 0 to 249;
2 process for calculating from 250 to 499;
3 process for calculating from 500 to 749;
4 process for calculating from 750 to 999;
Multiplication is working correctly;
I do not understand much of processes, and the problem lies in the parts of the processes, I can not do what I need;
Follow the code below:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/shm.h>
int id;
int main(){
int i;
int j;
int row;
int col;
int order;
long T1;
long T2;
float delta;
int process_1;
int process_2;
int process_3;
int process_4;
printf("Enter the order of the square matrices A and B: ");
scanf("%d", &order);
T1 = clock();
printf("\nThe square matrices A and B, are order matrices %d",order);
order = order - 1;
row = order;
col = order;
float A[row+1][col+1];
float B[row+1][col+1];
for(i = 0; i <= row; i++){
for(j = 0; j <= col; j++){
printf("\n\nEnter the value of the array A[%d][%d]: ",i+1,j+1);
scanf("%f", &A[i][j]);
printf("\nEnter the value of the array B[%d][%d]: ",i+1,j+1);
scanf("%f", &B[i][j]);
}
}
printf("\nThe multiplication of matrices A and B:\n\n");
id = shmget(IPC_PRIVATE, 100, 0600);
process_1 = fork();
process_2 = fork();
process_3 = fork();
process_4 = fork();
int *a;
a = shmat(id,0,0);
printf("\n\nprocess 1:\n\n");
if(process_1 == 0){
int P1 = 0;
if(P1 <= 249){
for(i = 0; i <= row; i++) {
for(j = 0; j <= col; j++) {
float C[row+1][col+1];
for(int AUX = 0; AUX <= order; AUX++) {
C[i][j] += A[i][AUX] * B[AUX][j];
}
printf("%.2f ",C[i][j]);
}
printf("\n");
}
}
exit(0);
}
printf("\n\nprocess 2:\n\n");
if(process_2 == 0){
int P2 = 250;
if(P2 >=250 && P2 <= 499){
for(i = 0; i <= row; i++) {
for(j = 0; j <= col; j++) {
float C[row+1][col+1];
for(int AUX = 0; AUX <= order; AUX++) {
C[i][j] += A[i][AUX] * B[AUX][j];
}
printf("%.2f ",C[i][j]);
}
printf("\n");
}
}
exit(0);
}
printf("\n\nprocess 3:\n\n");
if(process_3 == 0){
int P3 = 0;
if(P3 >=500 && P3 <= 749){
for(i = 0; i <= row; i++) {
for(j = 0; j <= col; j++) {
float C[row+1][col+1];
for(int AUX = 0; AUX <= order; AUX++) {
C[i][j] += A[i][AUX] * B[AUX][j];
}
printf("%.2f ",C[i][j]);
}
printf("\n");
}
}
exit(0);
}
printf("\n\nprocess 4:\n\n");
if(process_4 == 0){
int P4 = 0;
if(P4 >=750 && P4 <= 999){
for(i = 0; i <= row; i++) {
for(j = 0; j <= col; j++) {
float C[row+1][col+1];
for(int AUX = 0; AUX <= order; AUX++) {
C[i][j] += A[i][AUX] * B[AUX][j];
}
printf("%.2f ",C[i][j]);
}
printf("\n");
}
}
exit(0);
}
waitpid(process_1, NULL, 0);
waitpid(process_2, NULL, 0);
waitpid(process_3, NULL, 0);
waitpid(process_4, NULL, 0);
T2 = clock();
delta = (float)(T2-T1)/CLOCKS_PER_SEC;
printf("\n\Time %.5f seconds\n\n",delta);
return 0;
}
How can I fix this?
I would start from changing type int to pid_t for process identifiers, e.g.:
pid_t process_1;
and then would change:
process_1 = fork();
process_2 = fork();
process_3 = fork();
process_4 = fork();
to
pid_t pid = fork();
if (pid) {
process_1 = pid;
pid = fork();
}
if (pid) {
process_2 = pid;
pid = fork();
}
if (pid) {
process_3 = pid;
pid = fork();
}
if (pid)
process_4 = pid;
the idea is that we do fork() only in the parent process and skip forking in a child process. Otherwise your code forks processes as a tree, each child and parent processes call the next fork() after the previous, then their children do the same and so on four times.
The code above does not check if fork() returns the error code (-1). In the ideal world it is strongly recommended.
From the fork(2) man page:
Return Value
On success, the PID of the child process is returned in the parent,
and 0 is returned in the child. On failure, -1 is returned in the
parent, no child process is created, and errno is set appropriately.

char() represetation of an array

I had a program that I had to create which took a user inputted odd number between 1 to 99 and created a magic square which I have successfully done.
#include <stdio.h>
int main()
{
int n;
printf("\nThis programs creates a magic squares of a specified size.\n");
printf("The size must be an odd number between 1 and 99.\n");
printf("Enter the size of magic square: ");
scanf("%d", &n);
int magicsq[99][99];
int row = 0;
int col = (n - 1) / 2;
magicsq[row][col] = 1;
int i;
for(i = 2; i <= n * n; i++)
{
row = (row + n - 1) % n;
/* printf("i = %d\n", i);
printf("row %d\n", row);
col = (col % n); */
col = (col + 1) % n;
/* printf("col %d\n\n", col); */
if(magicsq[row][col] != 0)
{
row = (n + row + 2) % n;
col = (n + col - 1) % n;
/* printf("n = %d ; row = %d ; col = %d\n", n, row, col); */
}
magicsq[row][col] = i;
}
printf("\n");
int j;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
printf("%5d", magicsq[i][j]);
}
printf("\n");
}
return 0;
}
I came across another question which stated me to introduce two functions namely, void create_magic_square(int n, char magic_square[99][99]) and void print_magic_square(int n, char magic_square[99][99])
#include <stdio.h>
void create_magic_square(int n, char magic_square[99][99]);
void print_magic_square(int n, char magic_square[99][99]);
int main()
{
int n;
char **magic_square;
printf("\nThis programs creates a magic squares of a specified size.\n");
printf("The size must be an odd number between 1 and 99.\n");
printf("Enter the size of magic square: ");
scanf("%d", &n);
create_magic_square(n, magic_square[99][99]);
print_magic_square(n, magic_square[99][99]);
return 0;
}
void create_magic_square(int n, char magic_square[99][99])
{
int *magicsq[][];
magic_square[99][99] = magicsq[][];
int row = 0;
int col = (n - 1) / 2;
magicsq[row][col] = 1;
int i;
for(i = 2; i <= n * n; i++)
{
row = (row + n - 1) % n;
printf("i = %d\n", i);
printf("row %d\n", row);
/* col = (col % n); */
col = (col + 1) % n;
printf("col %d\n\n", col);
if(magicsq[row][col] != 0)
{
row = (n + row + 2) % n;
col = (n + col - 1) % n;
printf("n = %d ; row = %d ; col = %d\n", n, row, col);
}
magicsq[row][col] = i;
}
}
void print_magic_square(int n, char magic_square[99][99])
{
printf("\n");
int j;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
printf("%5d", magicsq[i][j]);
}
printf("\n");
}
}
Upon compiling, I am filled with tons of errors on my declaration of char type array and my usage of the parameters. I have googled char() parameters and types but I am not able to incorporate into my program.
I am new to c so constructive criticism is appreciated and helps me learn better if I am doing anything wrong.
Language: c99 ; Compiler: gcc
Of course there are lot of mistakes in your code related to pointers and arrays and those can't be completely explained in a single answer here.
I recommend you to study the pointers properly. Relationship between pointers and arrays, Multidimensional arrays are all need to be thoroughly understood before attempting to do what you are trying to.

Error getting shared memory for creating more than 6 child process

I am trying to understand how fork in c work. The problem that I am trying to solve is; given f(upper), I am trying to find f(1) + f(2) + .. f(upper).
I wanted to do multi process programming to have fork each child process and have each child process calculate f(x).
So f(1) , f(2) ... f(upper) is calculated by each child process.
The parent process should calculate following f(1) + .. + f(upper).
Here is my code
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include<sys/shm.h>
#include<sys/ipc.h>
int upper = 0;
int n = 0;
int main(int argc, char*argv[]){
pid_t pid;
if(argc != 2){
printf("Input one argument");
return -1;
}
upper = atoi(argv[1]);
int segment_id;
int *s;
pid_t *pids;
pids = (pid_t *) malloc(sizeof(int) * upper);
s = (int *) malloc(sizeof(int) * upper);
key_t key = 4141;
if((segment_id = shmget(key, upper * sizeof(int), IPC_CREAT | 0667))< 0) perror("shmget: failure");
if((s = shmat(segment_id, NULL, 0)) == (char *) -1){
perror("shmat : failure");
exit(1);
}
for(int i = 1; i <= upper; i++){
pid = fork();
if(pid == 0) {
n = i;
break;
}
pids[i] = pid;
}
if(pid > 0){
wait(1 * upper);
int totalSum;
for(int i = 0; i < upper; i++){
totalSum += s[i];
}
printf("Total sum = %d", totalSum);
} else {
sleep(2);
int sum = 0;
for(int i = 0; i <= n; i++){
sum += i;
}
s[n - 1] = sum;
printf("n => %d : sum %d\n", n, sum);
}
}
However whenever I try to run this program with argument more than 6.
I get Invalid argument error.
You are writing outside of the bounds of pids
pids = (pid_t *) malloc(sizeof(int) * upper);
...
for(int i = 1; i <= upper; i++){
pid = fork();
if(pid == 0) {
n = i;
break;
}
pids[i] = pid; /* Here */
}
Change to
for(int i = 1; i < upper; i++){

Resources