Я пишу программу, в которой я дважды разветвлялся, чтобы создать 2 дочерних процесса, которые отправляют информацию родителю через свои stdouts.Дети запускают программу, делая ее рекурсивной.То, что происходит, - то, что родитель, читая потомка, застревает в цикле чтения, но это не вечный цикл (есть конечный и ожидаемый результат);он просто не проходит мимо него.
char response1[256];
double complex r1[sizeof(workable)/sizeof(float)];
char* thing = NULL;
int countC1 = 1;
int bytesread;
char* response1Whole = NULL;
while((bytesread = read(pipefdc1b[0],response1, 256)) > 0){
fprintf(stderr,"PID:%d -> Reading Bytes from Child 1 Bytes read: %d\n\n", getpid(), bytesread);
if(bytesread == 256){
response1Whole = (char*) realloc(response1Whole, countC1*256 );
}else{
response1Whole = (char*) realloc(response1Whole, (countC1-1)*256+bytesread);
}
strcat(response1Whole, response1);
countC1++;
fprintf(stderr,"PID:%d -> Current Builts Input %s\n\n", getpid(), response1Whole);
}
fprintf(stderr,"PID:%d -> Child 1 Read\n\n", getpid());
Это фрагмент кода, который, я считаю, застревает.Он распечатывает все части «Текущий встроенный вход» и «Чтение байтов от дочернего элемента 1», но никогда не достигает части «Дочернее 1 чтение».Заметим, что есть конечный и детерминированный вывод, и то, что он читает, - это то, что ожидается, программа просто останавливается.
if(count == 1){
fprintf(stdout,"%s", st);
fflush(stdout);
exit(EXIT_SUCCESS);
}
Это блок кода, который определяет вывод.Я чувствую, что здесь может быть какая-то проблема, когда он не завершает свой поток вывода должным образом, но затем он снова завершается.
Вот код от создания каналов к «проблемной» области:
int pipefdc1a[2]; //p->c1
int pipefdc1b[2]; //c1->p||
int pipefdc2a[2]; //p->c1
int pipefdc2b[2]; //c2->p
if(pipe(pipefdc1a) == -1){
fprintf(stderr, "Pipe Creation Failed\n");
exit(EXIT_FAILURE);
}
if(pipe(pipefdc1b) == -1){
fprintf(stderr, "Pipe Creation Failed\n");
exit(EXIT_FAILURE);
}
if(pipe(pipefdc2a) == -1){
fprintf(stderr, "Pipe Creation Failed\n");
exit(EXIT_FAILURE);
}
if(pipe(pipefdc2b) == -1){
fprintf(stderr, "Pipe Creation Failed\n");
exit(EXIT_FAILURE);
}
//fprintf(stderr,"PID:%d -> Pipes Created\n\n", getpid());
fflush(stdout);
pid_t pid = fork();
pid_t pid2;
switch (pid) {
case -1:
fprintf(stderr, "Cannot fork!\n");
exit(EXIT_FAILURE);
case 0:
//child 1
close(pipefdc1a[1]);
close(pipefdc1b[0]);
close(pipefdc2a[0]);
close(pipefdc2a[1]);
close(pipefdc2b[0]);
close(pipefdc2b[1]);
dup2(pipefdc1a[0],STDIN_FILENO);
close(pipefdc1a[0]);
dup2(pipefdc1b[1], STDOUT_FILENO);
close(pipefdc1b[1]);
execlp("./forkFFT","forkFFT", NULL);
exit(EXIT_FAILURE);
default:
//parent
fflush(stdout);
pid2 = fork();
switch(pid2){
case -1:
fprintf(stderr, "Cannot fork!\n");
exit(EXIT_FAILURE);
case 0:
//child 2
//fprintf(stderr,"PID:%d -> New Child 2 Created\n\n", getpid());
close(pipefdc1a[1]);
close(pipefdc1a[0]);
close(pipefdc1b[0]);
close(pipefdc1b[1]);
close(pipefdc2a[1]);
close(pipefdc2b[0]);
dup2(pipefdc2a[0],STDIN_FILENO);
close(pipefdc2a[0]);
dup2(pipefdc2b[1], STDOUT_FILENO);
close(pipefdc2b[1]);
execlp("./forkFFT","forkFFT", NULL);
exit(EXIT_FAILURE);
default:
//parent
fprintf(stderr, "entered parent switch. PID1: %d, PID2: %d\n\n", pid, pid2);
write(pipefdc1a[1], stp1, evensize);
write(pipefdc2a[1], stp2, oddsize);
close(pipefdc1a[1]);
close(pipefdc2a[1]);
char response1[256];
char response2[256];
double complex r1[sizeof(workable)/sizeof(float)];
double complex r2[sizeof(workable)/sizeof(float)];
char* thing = NULL;
int countC1 = 1;
int bytesread;
char* response1Whole = NULL;
while((bytesread = read(pipefdc1b[0],response1, 256)) > 0){
fprintf(stderr,"PID:%d -> Reading Bytes from Child 1 Bytes read: %d\n\n", getpid(), bytesread);
if(bytesread == 256){
response1Whole = (char*) realloc(response1Whole, countC1*256 );
}else{
response1Whole = (char*) realloc(response1Whole, (countC1-1)*256+bytesread);
}
strcat(response1Whole, response1);
countC1++;
fprintf(stderr,"PID:%d -> Current Builts Input %s\n\n", getpid(), response1Whole);
}
fprintf(stderr,"PID:%d -> Child 1 Read\n\n", getpid());
char* token = strtok(response1Whole, "\n");
while(token != NULL){
double real = (double)strtof(token, &thing);
if(token == thing){
fprintf(stderr, "Real Part is NAN\n");
exit(EXIT_FAILURE);
}
fprintf(stderr, "Real Number Read from child 1: %lf. PID1: %d, PID2: %d\n\n", real, pid, pid2);
double imaginary = 0.0;
if(thing != NULL){
fprintf(stderr,"Thing String: %s\n", thing);
char* check = NULL;
imaginary = (double)strtof(thing, &check);
if(check == thing){
fprintf(stderr, "Imaginary Part is NAN\n");
exit(EXIT_FAILURE);
}
}
fprintf(stderr, "Imaginary part of number 1: %lf. PID1: %d, PID2: %d\n\n",imaginary, pid, pid2);
r1[countC1] = real + imaginary*I;
token = strtok(NULL,"\n");
}
fprintf(stderr, "made it 1!\n\n");
char* thing2 = NULL;
int countC2 = 0;
FILE* pipe2File = fdopen(pipefdc2b[0], "r");
while(fgets(response2, 256, pipe2File) != NULL){
fprintf(stderr, "Reading from child 2. PID1: %d, PID2: %d\n\n", pid, pid2);
double real = (double)strtof(response2, &thing2);
if(response1 == thing2){
fprintf(stderr, "Real Part is NAN\n");
exit(EXIT_FAILURE);
}
fprintf(stderr, "Real Number Read from child 2: %lf. PID1: %d, PID2: %d\n\n", real, pid, pid2);
double imaginary = 0.0;
if(thing2 != NULL && thing2[0] != '\n'){
fprintf(stderr,"Thing2 String: %s\n", thing2);
char* check2 = NULL;
imaginary = (double)strtof(thing2, &check2);
if(check2 == thing2){
fprintf(stderr, "Imaginary Part is NAN\n");
exit(EXIT_FAILURE);
}
}
fprintf(stderr, "Imaginary part of number 2: %lf. PID1: %d, PID2: %d\n\n",imaginary, pid, pid2);
r2[countC2] = real + imaginary*I;
countC2++;
}
fclose(pipe2File);
fprintf(stderr, "made it 2!\n\n");
waitpid(pid, &status, 0);
if(status == 1){
fprintf(stderr, "Child did not terminate normally!\n");
exit(EXIT_FAILURE);
}
waitpid(pid2, &status, 0);
if(status == 1){
fprintf(stderr, "Child did not terminate normally!\n");
exit(EXIT_FAILURE);
}
Я пробовал 2 разных цикла для дочерних элементов 1 и 2, потому что в какой-то момент я решил, что это проблема, ноэто не было.
Я немного на грани моего понимания C;если бы вы могли ответить и объяснить это было бы здорово.
Я пытаюсь соблюдать правило «Минимально необходимый код», но если вы чувствуете, что требуются другие вещи, пожалуйста, спросите, и я добавлю их.