C 程序在“fork()”和管道中存在问题

Posted

技术标签:

【中文标题】C 程序在“fork()”和管道中存在问题【英文标题】:C program having issues inside "fork()" and pipes 【发布时间】:2021-04-12 01:36:27 【问题描述】:

您好,我是 C 语言中亲子交流的初学者。我正在尝试使用 C 编程构建一个计算器,它只会从文件中读取数据,使用 fork()pipe 进行一些计算,然后确定输出。我能够从文件中读取运算符以及文件中的数字,但在 if(fork() == 0) 条件内使用 dup 时遇到问题。 close(1); 以上的一切都在工作,但之后的一切都不起作用。我使用输入流 0 读取第一个参数,使用流 3 读取第二个参数,并使用标准输出流 1 进行输出。我知道在那之后我必须设置加法、减法、乘法和除法的条件,然后在我弄清楚之后使用execl 来计算计算,但我无法弄清楚为什么我会遇到这个问题,任何帮助都会不胜感激谢谢!这是下面的代码和输入文件。为了程序,我们需要将文件名作为参数传递。例如./calc data.txt

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

#define MAXLEN 1000

int fds[100][2];
char operators[100];

int main(int argc, char *argv[]) 
    char line[MAXLEN], *temp;

    FILE *dataFile = fopen(argv[1], "r");
    //read the first line - it contains the configuration
    fgets(line, MAXLEN, dataFile);

    // sample content for line: a + b - c
    strtok(line, " \n"); //skip the symbol representing variable/parameter
    int count=0;
    while (temp = strtok(NULL, " \n")) 
            operators[count] = temp[0];
            printf("operator: %c\n", operators[count]);
            count++;
            strtok(NULL, " \n"); //skip the symbol representing variable/parameter
    
    int x[count+1];
    int num = 0;
    while (fscanf(dataFile, "%d", &x[num]) > 0)
            printf("%d\n", x[num]);
            num++;
            
    for(int h=0; h<count*2+1; h++)
            pipe(fds[h]);
            printf("%d \n",h);
    
    printf("Count: %d\n", count);
    for(int i = 0; i < count; i++)
            //printf("%c\n", operators[i]);
            if (fork() == 0)
                    //printf("Value of operators: %c\n",operators[i]);
                    close(0);
                    dup(fds[2*i][0]);
                    close(3);
                    dup(fds[2*i+1][0]);
                    //printf("After close(3)\n");
                    if(operators[i] == '+')
                            printf("Add \n");
                    close(1);
                    printf("After close(0) \n");
                    dup(fds[2*i+2][1]);
                    printf("Value of operators: %c\n", operators[i]);
            if(operators[i] == '+')
                            printf("Add %n");
            `
          
   `

【问题讨论】:

您为此使用fork 有什么特别的原因吗?您正在为输入中的每个运算符创建一个流程。我不确定这是否真的是你想要做的。 有人告诉我使用 fork OT:关于:FILE *dataFile = fopen(argv[1], "r"); 在没有首先检查argc 以确保用户实际输入了预期的命令行参数之前,永远不要访问argv[0] 以外的地方 OT:请不要使用 进行缩进。每个编辑器都设置为 使用特定数量的字符(默认为 8 个字符)强烈建议每个缩进级别使用 4 个空格 关于:while (temp = strtok(NULL, " \n")) 分配总是导致true 这不是你想要的。建议:while ( (temp = strtok(NULL, " \n"))) ) (注意额外的括号)将检查 temp 的内容是否为 != NULL 【参考方案1】:

文件描述符 1 引用 stdout。如果您关闭它,您对 printf 的调用将失败,因为它会尝试打印到已关闭的流。

【讨论】:

那我该怎么做呢?因为我还必须检查运算符才能计算。我该怎么做? 你能做什么?您可以完全按照使用close(1) 的方式关闭文件描述符1。但文件描述符 1 指的是 stdout - 标准输出流,即您的终端。当你关闭它时,你不能再向它打印输出了。 如何确保close(1) 之后的 if 条件有效?因为最后这就是我需要的,我也可以在里面使用execl,如果条件它会起作用吗? @eliesmith 条件应该可以正常工作。问题是当条件为真时您调用的printf。它出错是因为它无法打印到您刚刚关闭的流中。请阅读一些对标准 I/O 以及进程和分叉的介绍,因为从代码来看,您似乎对如何使用它没有正确的想法。 你能帮助mw吗?我必须为所有数学运算符这样做

以上是关于C 程序在“fork()”和管道中存在问题的主要内容,如果未能解决你的问题,请参考以下文章

Unix上用C程序实现pipe管道命令“ | “(pipe,fork,dup2,close,execl,重定向)

命名管道和分叉令人头疼

多线程程序中的fork

popen() 可以制作像 pipe() + fork() 这样的双向管道吗?

C 中的管道 - 我必须使用 fork 吗?

命名管道,使用 Fork()