c - C 语言中 fgets 不返回 NULL

标签 c pipe fgets

循环本来应该中断,但它一直卡在fgets上。 process_P1 通过管道与 inputHandler 对话。问题是 inputHandler 无法意识到 process_P1 何时停止写入...“lalala”printf 永远不会到达。

void process_P1(char *argv[], int fd[2], pid_t child)
{
    int bytes = 0;

    static char bufferIn[BUFFER_SIZE];
    static char bufferOut[BUFFER_SIZE];

    char line[BUFFER_SIZE];

    // close reading end of pipe
    close(fd[0]);

    FILE *in = fopen(getInput(argv), "r");
    FILE *out = fdopen(fd[1], "w");

    if (in == NULL) {
            sys_err("fopen(r) error (P1)");
    }
    int ret = setvbuf(in, bufferIn, _IOLBF, BUFFER_SIZE);
    if (ret != 0) {
            sys_err("setvbuf error (P1)");
    }

    if (out == NULL) {
            sys_err("fdopen(w) error (P1)");
    }
    ret = setvbuf(out, bufferOut, _IOLBF, BUFFER_SIZE);
    if (ret != 0) {
            sys_err("setvbuf error (P1)");
    }

    while (fgets(line, BUFFER_SIZE, in) != NULL)
    {
            fprintf(out, "%s", line);
            bytes += count(line) * sizeof(char);
    }

    // alert P2 to stop reading
    //fprintf(out, "%s", STOP);

    fclose(in);
    fflush(out);
    fclose(out);

    printf("P1: file %s, bytes %d\n", getInput(argv), bytes);

    // wait P2 ends
    if (waitpid(child, NULL, 0) < 0) {
            sys_err("waitpid error (P1)");
    }
}

void *inputHandler(void *args)
{
    int ret;

    static char bufferIn[BUFFER_SIZE];
    char line[BUFFER_SIZE];
    struct node *iterator;

    int *fd = (int*)args;

    close(fd[1]);

    FILE *in = fdopen(fd[0], "r");
    if (in == NULL) {
            sys_err("fdopen(r) error (P2)");
    }
    ret = setvbuf(in, bufferIn, _IOLBF, BUFFER_SIZE);
    if (ret != 0) {
            sys_err("setvbuf(in) erro (P2)");
    }

    while (fgets(line, BUFFER_SIZE, in) != NULL)
    {
    //      printf("%s", line);
            iterator = firstArg;
            while (iterator->next != NULL)
            {
                    ret = sem_wait(&(iterator->sem));
                    if (ret == 0) {
                            strcat(iterator->buffer, line);
                    } else {
                            sys_err("sem_wait error");
                    }
                    ret = sem_post(&(iterator->sem));
                    if (ret != 0) {
                            sys_err("sem_post error");
                    }
                    iterator = iterator->next;
            }
            line[0] = '\0';
    }
    printf("lalala\n");
    iterator = firstArg;
    while (iterator->next != NULL)
    {
            ret = sem_wait(&(iterator->sem));
            if (ret != 0) {
                    sys_err("sem_wait error");
            }
            iterator->shouldStop = 1;
            ret = sem_post(&(iterator->sem));
            if (ret != 0) {
                    sys_err("sem_post error");
            }
            iterator = iterator->next;
    }

    fclose(in);

    return NULL;
}

最佳答案

问题可能不在您显示的代码中。既然您提到了管道,那么您的问题可能出在与此相关的管道中 - 最有可能的是,您在管道的一端执行了 dup2() ,以使其成为标准输入或标准输出,但是您忘记关闭复制的文件描述符,或者忘记关闭另一端。在没有进程可以写入它正在读取的管道之前,fgets() 不会终止。如果正在读取的进程仍然打开管道的写入端,它将停留在读取状态,等待写入内容。

所以,仔细看看你的管道代码。确保在将一端复制到标准输入或标准输出后,已关闭 pipe() 返回的两个值。

关于c - C 语言中 fgets 不返回 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13060939/

相关文章:

linux - zcat 文件是 gzip 格式还是非 gzip 格式

c++ - 子进程和父进程之间的交互式双向通信(使用管道)

c - 如何在循环中对整数使用 fgets 和 sscanf

c - 扫描到 fgets C

C++ 什么是 NULL 指针值?

c - 使用多线程计算数据但并没有减少时间

c - 这个打印函数如何将指针移动到链表中的下一项?

c - 用 C 打印存档文件的内容

bash - 杀死管道左侧的进程

C:读取单词并在其中包含\n,但不包含空格