【问题标题】:Discrepancies in Matrix Data Communicated Between Parent and Child Process父子进程之间通信的矩阵数据的差异
【发布时间】:2014-03-23 05:37:31
【问题描述】:

对于我的一个项目,我需要在进程之间传递矩阵(稍后将在运行时确定各种大小),并对它们执行操作。这将在 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");
    }
}

【问题讨论】:

    标签: c arrays matrix process pipe


    【解决方案1】:

    每个矩阵都是一个指针数组,其中每个指针指向一个整数数组。因此,您用来在父子之间传递矩阵的方法不会按您希望的方式工作。

    您正在做的是通过管道传递四个指针(其中只有前两个是有效的)。由于孩子是父母的副本,这些指针实际上指向父母地址空间中的原始矩阵。因此,父级打印原始矩阵。

    您想要做的是通过管道传递整数值并在另一侧重建矩阵。需要类似于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 *。这很糟糕,有两个原因。

    1. 数组中只有两个指针
    2. 通过管道传递指针与通过管道发送数据不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-19
      • 1970-01-01
      • 2012-04-15
      • 1970-01-01
      • 2016-05-26
      • 1970-01-01
      • 2022-06-10
      相关资源
      最近更新 更多