【发布时间】:2020-08-03 10:29:30
【问题描述】:
我知道这听起来不真实的“意外的变量变化”。由于我无法发现问题,所以我使用了该标题...
首先,这是我的作业。作业是关于从文件中读取两个矩阵然后创建 4 个子进程,父进程将(通过管道)发送四分之一的矩阵到子进程。子进程将在之后进行计算,他们会将计算出的索引发送回父进程(再次通过管道。尝试在此处实现双向管道。)因此父进程会将计算值打印到标准输出并返回。
目前我所做的是从文件中读取这些矩阵,创建 3 个进程(逐步进行),将 1/4 的矩阵发送到每 3 个进程并尝试检查我是否成功。
问题是“通常”发生的情况是我看到third_start 变量已更改(在同一范围内),因此它甚至没有进入循环。
我还观察到了更多的事情;
- 将输出重定向到某个文件时,数据看起来像我的程序的 %10 写在那里。
- 如果我提供具有较小值的矩阵,例如 4x4 矩阵。
third_start的问题不会发生。
我确定我在做一些愚蠢的事情。
这是我的代码的相关部分。 (有点乱,这不是我发送作业的方式。请忽略关于矩阵的计算。)
int pipe_fds[2]; //first pipe
int pipe_fds2[2];//second pipe
int pipe_fds3[2];//third pipe
int pipe_fds4[2];//fourth pipe
int pip_ret, pip_ret2, pip_ret3, pip_ret4;
int pid2,pid3,pid4,pid5; //assumed p1 is parent and 2,3,4,5 are child processes.
int single_x; //store single_x val;
int single_y;
pip_ret = pipe(pipe_fds);
pid2 = fork();
if(pip_ret == -1)
{
fprintf(stderr, "%s\n", "Unable to create pipe\n");
exit(1);
}
else if(pid2 == 0)
{
if (close(pipe_fds[1]) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
int first_quarter_x[_pow(2, n) / 2][_pow(2, n) / 2];
int first_quarter_y[_pow(2, n) / 2][_pow(2, n) / 2];
for(i = 0 ; i < _pow(2, n) / 2 ; ++i)
{
for(j = 0 ; j < _pow(2, n) / 2; ++j)
{
if(read(pipe_fds[0], &single_x, sizeof(single_x)) <= 0)
{
perror("read failed ");
exit(EXIT_FAILURE);
}
first_quarter_x[i][j] = single_x;
if(read(pipe_fds[0], &single_y, sizeof(single_y)) <= 0)
{
perror("read failed ");
exit(EXIT_FAILURE);
}
first_quarter_y[i][j] = single_y;
fprintf(stderr,"(2)Child with pid %d received value %d\n",getpid(), single_x);
fprintf(stderr,"(2)Child with pid %d received value %d\n",getpid(), single_y);
}
}
for(i = 0 ; i < _pow(2, n) / 2 ; ++i)
{
for(j = 0 ; j < _pow(2, n) / 2; ++j)
{
if(matrixA[i][j] == first_quarter_x[i][j])
{
fprintf(stderr,"Good2a\n" );
}
else
{
fprintf(stderr,"Bad2a.\n" );
}
}
fprintf(stderr,"\n" );
}
for(i = 0 ; i < _pow(2, n) / 2 ; ++i)
{
for(j = 0 ; j < _pow(2, n) / 2; ++j)
{
if(matrixB[i][j] == first_quarter_y[i][j])
{
printf("Good2b\n" );
}
else
{
printf("Bad2b.\n" );
}
}
fprintf(stderr,"\n" );
}
exit(EXIT_SUCCESS);
}
pip_ret2 = pipe(pipe_fds2);
pid3 = fork();
if(pip_ret2 == -1)
{
fprintf(stderr, "%s\n", "Unable to create pipe for 3.process\n");
exit(1);
}
else if(pid3 == 0)
{
if (close(pipe_fds2[1]) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
int second_start = _pow(2, n) / 2;
int second_quarter_x[_pow(2, n) / 2][_pow(2, n) / 2];
int second_quarter_y[_pow(2, n) / 2][_pow(2, n) / 2];
for(i = 0 ; i < _pow(2, n) / 2 ; ++i)
{
for(j = second_start ; j < _pow(2, n); ++j)
{
if(read(pipe_fds2[0], &single_x, sizeof(single_x)) <= 0)
{
perror("read failed ");
exit(EXIT_FAILURE);
}
second_quarter_x[i][j] = single_x;
if(read(pipe_fds2[0], &single_y, sizeof(single_y)) <= 0)
{
perror("read failed ");
exit(EXIT_FAILURE);
}
second_quarter_y[i][j] = single_y;
fprintf(stderr,"(3)Child with pid %d received value %d\n",getpid(), single_x);
fprintf(stderr,"(3)Child with pid %d received value %d\n",getpid(), single_y);
}
}
for(i = 0 ; i < _pow(2, n) / 2 ; ++i)
{
for(j = second_start ; j < _pow(2, n) ; ++j)
{
if(second_quarter_x[i][j] == matrixA[i][j])
{
fprintf(stderr,"Good3a \n" );
}
else
{
fprintf(stderr,"Bad3a\n" );
}
}
fprintf(stderr,"\n" );
}
for(i = 0 ; i < _pow(2, n) / 2 ; ++i)
{
for(j = second_start ; j < _pow(2, n) ; ++j)
{
if(second_quarter_y[i][j] == matrixB[i][j])
{
fprintf(stderr,"Good3b \n" );
}
else
{
fprintf(stderr,"Bad3b\n" );
}
}
fprintf(stderr,"\n" );
}
exit(EXIT_SUCCESS);
}
pip_ret3 = pipe(pipe_fds3);
pid4 = fork();
if(pip_ret3 == -1)
{
fprintf(stderr, "%s\n", "Unable to create pipe for 4.process\n");
exit(1);
}
else if(pid4 == 0)
{
if (close(pipe_fds3[1]) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
int third_start = _pow(2, n) / 2;
printf("THIRD START IS %d\n",third_start ); //here it prints normal.
int third_quarter_x[_pow(2, n) / 2][_pow(2, n) / 2];
int third_quarter_y[_pow(2, n) / 2][_pow(2, n) / 2];
for(i = third_start ; i < _pow(2, n) ; ++i)
{
for(j = 0 ; j < _pow(2, n) / 2; ++j)
{
if(read(pipe_fds3[0], &single_x, sizeof(single_x)) <= 0)
{
perror("read failed ");
exit(EXIT_FAILURE);
}
third_quarter_x[i][j] = single_x;
if(read(pipe_fds3[0], &single_y, sizeof(single_y)) <= 0)
{
perror("read failed ");
exit(EXIT_FAILURE);
}
third_quarter_y[i][j] = single_y;
fprintf(stderr,"(4)Child with pid %d received value %d\n",getpid(), single_x);
fprintf(stderr,"(4)Child with pid %d received value %d\n",getpid(), single_y);
}
}
printf("THIRD START IS %d\n",third_start ); //then it prints something anormal...
for(i = third_start ; i < _pow(2, n) ; ++i)
{
for(j = 0 ; j < _pow(2, n) / 2; ++j)
{
if(third_quarter_x[i][j] == matrixA[i][j])
{
fprintf(stderr,"Good4a \n" );
}
else
{
fprintf(stderr,"Bad4a\n" );
}
}
printf("\n" );
}
for(i = third_start ; i < _pow(2, n) ; ++i)
{
for(j = 0 ; j < _pow(2, n) / 2; ++j)
{
if(third_quarter_x[i][j] == matrixB[i][j])
{
fprintf(stderr,"Good4b \n" );
}
else
{
fprintf(stderr,"Bad4b\n" );
}
}
fprintf(stderr,"\n" );
}
exit(EXIT_SUCCESS);
}
//parent start
if (close(pipe_fds[0]) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
fprintf(stderr,"First quarter beginning \n");
for(i = 0 ; i < _pow(2, n) / 2 ; ++i)
{
for(j = 0 ; j < _pow(2, n) / 2; ++j)
{
single_x = matrixA[i][j];
single_y = matrixB[i][j];
write(pipe_fds[1], &single_x, sizeof(single_x));
write(pipe_fds[1], &single_y, sizeof(single_y));
fprintf(stderr,"Parent with pid %d sent value to 2 %d\n",getpid(), single_x);
fprintf(stderr,"Parent with pid %d sent value to 2 %d\n",getpid(), single_y);
}
}
wait(NULL);
fprintf(stderr,"First quarter end\n \n");
fprintf(stderr,"Second quarter beginning\n");
if (close(pipe_fds2[0]) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
int sec = _pow(2,n) / 2;
for(i = 0 ; i < _pow(2, n) / 2 ; ++i)
{
for(j = sec ; j < _pow(2, n); ++j)
{
single_x = matrixA[i][j];
single_y = matrixB[i][j];
write(pipe_fds2[1], &single_x, sizeof(single_x));
write(pipe_fds2[1], &single_y, sizeof(single_y));
fprintf(stderr,"Parent with pid %d sent value to 3 %d\n",getpid(), single_x);
fprintf(stderr,"Parent with pid %d sent value to 3 %d\n",getpid(), single_y);
}
}
wait(NULL);
fprintf(stderr,"Second quarter end\n");
fprintf(stderr,"Third quarter beginning\n");
if (close(pipe_fds3[0]) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}
int third = _pow(2,n) / 2;
for(i = third ; i < _pow(2, n) ; ++i)
{
for(j = 0 ; j < _pow(2, n) / 2; ++j)
{
single_x = matrixA[i][j];
single_y = matrixB[i][j];
write(pipe_fds3[1], &single_x, sizeof(single_x));
write(pipe_fds3[1], &single_y, sizeof(single_y));
fprintf(stderr,"Parent with pid %d sent value to 4 %d\n",getpid(), single_x);
fprintf(stderr,"Parent with pid %d sent value to 4 %d\n",getpid(), single_y);
}
}
wait(NULL);
fprintf(stderr,"Third quarter end\n");
【问题讨论】:
-
这可能是内存损坏的情况。申请
valgrind。 -
可能与问题无关,但你应该检查
pipe()是否在在你fork之前失败。否则,父母和孩子都会做这个检查。 -
你在所有子进程中有很多重复的代码,你应该把它放到一个函数中。
-
仅供参考:
_pow(2, n) / 2与_pow(2, n-1)相同 -
@Barmar 1-)确定我应该在创建管道后检查返回值。 2-)我知道那里很乱,肯定会清理那里。 3-)如果我可怜的 _pow 函数不知道如何计算 2^(-1) 怎么办 :)