对于我的项目,我需要在进程之间传递矩阵(稍后将在运行时确定各种大小),并对它们执行操作。这将在UNIX系统上执行。
在自学fork()
和pipe()
时,我设法在某些过程之间建立了两个单向管道(一个从父到孩子,反之亦然)。
=============================================== ============
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define READ_END 0
#define WRITE_END 1
#define MATRIX_N 2
void print_mat(int**, int);
int main(void){
// INITIALIZE
int **w_mat, **r_mat, **return_mat, i, j;
int fd1[2];
int fd2[2];
pid_t pid;
// Allocate memory for respective arrays
w_mat = (int**) malloc(sizeof(int *) * MATRIX_N);
for( i = 0 ; i < MATRIX_N ; i++ ){
*(w_mat + i) = (int*) malloc (sizeof(int *) * MATRIX_N);
}
r_mat = (int**) malloc(sizeof(int *) * MATRIX_N);
for( i = 0 ; i < MATRIX_N ; i++ ){
*(r_mat + i) = (int*) malloc (sizeof(int *) * MATRIX_N);
}
return_mat = (int**) malloc(sizeof(int *) * MATRIX_N);
for( i = 0 ; i < MATRIX_N ; i++ ){
*(return_mat + i) = (int*) malloc (sizeof(int *) * MATRIX_N);
}
// Assign initial values to matrix for writing
w_mat[0][0] = 2;
w_mat[0][1] = 7;
w_mat[1][0] = 12;
w_mat[1][1] = 9;
// Initialize and check pipes respectively
if( pipe(fd1) == -1){
fprintf(stderr, "Pipe failed");
return 1;
}
if( pipe(fd2) == -1){
fprintf(stderr, "Pipe failed");
return 1;
}
// Fork a child, then check it
pid = fork();
if( pid < 0 ){
fprintf(stderr, "Fork failed");
}
if( pid > 0 ){ /* PARENT */
// Close unnecessary pipe ends
close(fd1[READ_END]);
close(fd2[WRITE_END]);
printf("\nMatrix to send to child: ");
print_mat(w_mat, MATRIX_N);
// Write to pipe 1, matrix for child, then close pipe
write(fd1[WRITE_END], w_mat, MATRIX_N * MATRIX_N * sizeof(int*));
// Wait for child to process values, write, and terminate
wait(NULL);
// Read values from pipe 2
read(fd2[READ_END], return_mat, MATRIX_N * MATRIX_N * sizeof(int*));
printf("\nDoubled matrix received from child: ");
print_mat(return_mat, MATRIX_N);
// Close used pipe ends
close(fd2[READ_END]);
close(fd1[WRITE_END]);
}else{ /* CHILD */
// Close unnecessary pipe ends
close(fd1[WRITE_END]);
close(fd2[READ_END]);
// Read from pipe 1 the matrix from the parent
read(fd1[READ_END], r_mat, MATRIX_N * MATRIX_N * sizeof(int*));
printf("\nReceived matrix from parent to double: ");
print_mat(r_mat, MATRIX_N);
// Double the values in the matrix from parent
for( i = 0 ; i < MATRIX_N ; i++ ){
for( j = 0 ; j < MATRIX_N ; j++){
r_mat[i][j] = r_mat[i][j] * MATRIX_N;
}
}
printf("\nDoubled matrix to send to parent: ");
print_mat(r_mat, MATRIX_N);
// Write to pipe 2, the doubled matrix to be received by parent
write(fd2[WRITE_END], r_mat, MATRIX_N * MATRIX_N * sizeof(int*));
// Close used pipe ends
close(fd2[WRITE_END]);
close(fd1[READ_END]);
}
// Terminate
return 0;
}
=============================================== ============
=============================================== ============
Matrix to send to child:
| 2 7 |
| 12 9 |
Received matrix from parent to double:
| 2 7 |
| 12 9 |
Doubled matrix to send to parent:
| 4 14 |
| 24 18 |
Doubled matrix received from child:
| 2 7 |
| 12 9 |
=============================================== ============
写入之前的数组是正确的,似乎不知何故在将孩子从孩子写入管道2并在孩子终止后从所述管道读回来的时候;价值回归到了原来的样子。我不相信它可能是进程篡改它,因为每个都有自己的变量数组来存储数据,除了管道之外,实际上没有实例,在我的程序的if语句中,进程直接影响另一个数组 - 据我所知,就是这样。
实际上,是否存在父或子间接影响我不考虑的写入和读取数组的实例?如果是这样,我怎么能控制住这个?如果没有,我到底哪里出错了?我的管道实施本身是否存在缺陷?我真的不确定要找什么。
也;在字段实例的最左边,我的矩阵打印功能是罪魁祸首,这就是:
void print_mat(int** a, int n){
int i, j;
for( i = 0 ; i < n ; i++){
printf("\n| ");
for( j = 0 ; j < n ; j++){
printf("%d", a[i][j]);
if( j != n - 1){
printf(" ");
}
}
printf(" |\n");
}
}
答案 0 :(得分:0)
每个矩阵都是一个指针数组,每个指针都指向一个int数组。因此,用于在父级和子级之间传递矩阵的方法将无法按您希望的方式工作。
你正在做的是在管道上传递四个指针(其中只有前两个有效)。由于子项是父项的副本,这些指针实际上指向父项地址空间中的原始矩阵。因此,父母打印原始矩阵。
您要做的是在管道中传递整数值,并在另一侧重建矩阵。将单个值写入管道需要类似于print_mat
函数的代码。在接收方,需要读取这些值并将其存储在阵列中的适当位置。
让我看看我是否可以用一个例子来澄清。如果数组声明为
int w_mat[2][2];
然后你可以像这样传输整个数组
write(fd1[WRITE_END], w_mat, 2*2 * sizeof(int) );
但事实上数组相当于这个
int *w_mat[2];
w_mat[0] = malloc( 2 * sizeof(int) );
w_mat[1] = malloc( 2 * sizeof(int) );
因此,行
write(fd1[WRITE_END], w_mat, MATRIX_N * MATRIX_N * sizeof(int*));
正在向管道写入四个int *
。这有两个原因。