Детерминантная матрица, вычисляемая в C через трубу. код ревизии
Разработка программы осуществляется с использованием механизмов IPC одной из следующих задач: Способ - "Каналы". Реализуйте вычисление определителя квадратной матрицы, расширив его на определители более низкого порядка. "Основной" процесс отправляет задания "управляемые" процессы, но последние выполняют вычисление определителей, а затем вычисляют результат основного процесса. Другими словами, нужно использовать функцию pipe. У меня есть рабочая программа, но без механизмов IPC. Я не знаю о функции трубы и как она работает.
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
int determinant(int n, double mat[n][n])
{
int i,j,i_count,j_count, count=0;
double array[n-1][n-1], det=0;
if(n==1) return mat[0][0];
if(n==2) return (mat[0][0]*mat[1][1] - mat[0][1]*mat[1][0]);
for(count=0; count<n; count++)
{
i_count=0;
for(i=1; i<n; i++)
{
j_count=0;
for(j=0; j<n; j++)
{
if(j == count) continue;
array[i_count][j_count] = mat[i][j];
j_count++;
}
i_count++;
}
det += pow(-1, count) * mat[0][count] * determinant(n-1,array);
}
return det;
}
int main()
{
int i, j, dim;
printf("Enter n\n");
scanf("%d", &dim);
double matrix[dim][dim];
printf("Enter matrix:\n");
for(i = 0; i < dim; i++)
{
for(j = 0; j < dim; j++)
{
scanf("%lf \n", &matrix[i][j]);
}
}
double x = determinant(dim, matrix);
printf("Determinant = %g\n", x);
return 0;
}
1 ответ
Несколько замечаний: канал является однонаправленным, процесс записывает и процесс читает. Так что, когда вы запускаете канал, если процесс читает из канала, следует закрыть сторону записи канала и наоборот. В противном случае вы рискуете отправить данные вместо того, чтобы отправить его другому процессу. Канал может быть запущен до fork(), а дочерний процесс наследует канал (как и весь стек, кроме pid).
В этом примере родительский процесс запрашивает входную матрицу, затем отправляет ее дочернему процессу, дочерний процесс вычисляет определитель и выводит его на экран:
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include <unistd.h>
int determinant(int n, double mat[n][n])
{
int i,j,i_count,j_count, count=0;
double array[n-1][n-1], det=0;
if(n==1) return mat[0][0];
if(n==2) return (mat[0][0]*mat[1][1] - mat[0][1]*mat[1][0]);
for(count=0; count<n; count++)
{
i_count=0;
for(i=1; i<n; i++)
{
j_count=0;
for(j=0; j<n; j++)
{
if(j == count) continue;
array[i_count][j_count] = mat[i][j];
j_count++;
}
i_count++;
}
det += pow(-1, count) * mat[0][count] * determinant(n-1,array);
}
return det;
}
int main()
{
int i, j, dim;
int fd[2];
pipe(fd);
pid_t pid=fork();
if(pid)
{
// Father process
close(fd[0]); // close the reading side of the pipe
char buffer[100];
printf("Enter n\n");
fgets(buffer,100,stdin);
dim=atoi(buffer); // gets a float with atof
double matrix[dim][dim];
printf("Enter matrix:\n");
for(i = 0; i < dim; i++)
{
for(j = 0; j < dim; j++)
{
fgets(buffer,100,stdin);
matrix[i][j]=atof(buffer);
}
}
write(fd[1],&dim,sizeof(double)); // write the size of the matrix
write(fd[1], matrix, dim*dim*sizeof(double)); // write the matrix
close(fd[1]);
}
else
{
// Child process
close(fd[1]); // close the writing side of the pipe
int dim;
read(fd[0], &dim, sizeof(double)); // read the dimension
double matrix[dim][dim]; // read the matrix
read(fd[0], matrix, dim*dim*sizeof(double));
printf("%d",determinant(dim, matrix));
close(fd[0]);
}
return 0;
}
Важно: если размеры отрицательные, вы, вероятно, имеете ошибку сегментации или что-то в этом роде, поэтому также проверьте, что dim является приемлемым значением.
В примере я использовал fgets, потому что мне не нравится scanf, это создает проблемы с очисткой буфера. К сожалению, способ очистки буфера зависит также от системы, fflush(stdin) отлично работает на Windows, но на Linux вы должны подать в суд другой метод. Не стесняйтесь использовать scanf при условии, что вы можете очистить буфер ввода.