我正在尝试发送一个大数组,其中一半的值由子进程计算,另一半由父进程计算。我希望父进程从子进程获取一半数组的计算值,并将两个进程的两个数组合并/连接在一起,这样我就有一个最终数组,它是子数组和父数组计算加在一起的乘积。我尝试仅使用管道方法。我当前的代码使用“虚拟”数组,它是子进程的确定数组计算。然后,该数组通过管道传递到父进程,这允许将父进程的 Test->iterations 数组结果全部添加到一起。该数组在名为 Test 的结构中定义,其格式为:
typedef struct{
int *iterations
int height;
int width;
int start;
int end;
} Test;
由于这是一个 2D 数组,因此迭代的大小为 Test->width * Test->height * sizeof(int))。我还使用块读取和写入函数发送数组,因为它是一个非常大的数组。 我的并行程序函数(生成两个进程的函数)遵循以下格式:
int main(){
Test t;
t.height=1000;
t.width=1000;
if ((t->iterations = malloc(t->width * t->height * sizeof(int))) ==
NULL) {
perror("Cannot allocate memory (iterations)");
exit(EXIT_FAILURE);
}
processes(Test *);
}
void processes(Test *){
int p2c[2], c2p[2];
int i,j,k;
int half;
int *dummy = malloc(Test->width*Test->height*sizeof(int));
if(dummy==NULL){
perror("Malloc Error");
exit(EXIT_FAILURE);
}
for (i = 0; i < Test->height; i++) {
for (j = 0; j < Test->width; j++) {
dummy[i * Test->width + j] = 0.0;
}
}
half=Test->height >> 1;
pipe(p2c);
pipe(c2p);
if(fork()==0){
Test->start=0;
Test->end=half;
Compute(Test);
for(i=Test->start;i<Test->end;i++){
for(j=0;j<Test->width;j++){
dummy[i*Test->width+j]=Test->iterations[i*Test->width+j];
}
}
chwrite(c2p[WRITE], (char*)dummy, Test->width * half * sizeof(int), 2048);
printf("Sending Iterations\n");
close(p2c[READ]);
close(c2p[WRITE]);
exit(EXIT_SUCCESS);
}
else{
Test->start=half;
Test->end=Test->height;
Compute(Test);
sleep(1);
chread(c2p[READ], (char*)dummy, Test->width * half * sizeof(int), 2048);
printf("Reading Iterations\n");
wait(NULL);
for(i=0;i<Test->height;i++){
for(j=0;j<Test->width;j++){
Test->iterations[i*Test->width+j]=dummy[i*Test->width+j];
}
}
但是,当我这样做时,迭代数组充满了零。有什么问题以及如何解决这个问题?我的chunk读写函数如下:
void chwrite(int fd, char *buf, int count, int chunksize){
int numChunks = (int)(count/chunksize);
int remsize = count-numChunks*chunksize;
int i, j;
for(i=0,j=0; i<numChunks; j+=chunksize,i++){
write(fd, &(buf[j]), chunksize);
}
write(fd, &(buf[j]),remsize);
}
void chread(int fd, char *buf, int count, int chunksize){
int numChunks = (int)(count/chunksize);
int remsize=count-numChunks*chunksize;
int i,j;
for(i=0,j=0; i<numChunks; j+=numChunks, i++){
read(fd, &(buf[j]),chunksize);
}
read(fd, &(buf[j]) ,remsize);
}
chwrite
和
chread
函数不会检查错误或不完整的写入或读取。另外,
chread
中存在一个错误,其中
j
增加了
numChunks
而不是
chunksize
:
for(i=0,j=0; i<numChunks; j+=numChunks, i++){
read(fd, &(buf[j]),chunksize);
}
这里是 chread
的可能替代品,用于检查错误并允许不完整的读取。如果已读取任何内容,则返回读取的数量;如果未读取任何内容且要读取的数量为 0 或遇到文件结束条件,则返回 0;如果未读取任何内容且遇到错误,则返回 -1 :
int chread(int fd, char *buf, int count, int chunksize){
int done = 0;
int rc = count ? -1 : 0;
while (done < count) {
if (chunksize > done - count) {
chunksize = done - count;
}
rc = read(fd, &buf[done], chunksize);
if (rc <= 0) {
break;
}
done += rc;
}
return done ? done : rc;
}
这是一个替换 chwrite
功能。它与
chread
类似,只是不检查文件结束条件。 (文件结束条件在写入时没有意义,并且正常运行的
write
调用不应返回 0,除非调用计数为 0。):
int chwrite(int fd, const char *buf, int count, int chunksize){
int done = 0;
int rc = count ? -1 : 0;
while (done < count) {
if (chunksize > done - count) {
chunksize = done - count;
}
rc = write(fd, &buf[done], chunksize);
if (rc < 0) {
break;
}
done += rc;
}
return done ? done : rc;
}