使用 fgets 在多个进程中从重定向到 stdin 的文件中读取行

问题描述 投票:0回答:1

我正在尝试制作一个 C 程序,根据一个参数创建多个进程,然后让它们全部开始从 stdin 读取行,然后对它们执行操作(现在我只是将它们打印到屏幕上)。理想情况下,我能够在运行时将输入重定向到文件,如下所示:

./a.out 3 < batchcmds
。使用我当前的代码,当我手动输入输入时,一切都会按预期运行(据我所知),但是当我将输入重定向到我的文件
batchcmds
时,它只读取第一行,然后读取乱码。

~$ ./a.out 3 < batchcmds 
Main process 35e2e2
p35e2e2: Created child process 35e2e3
p35e2e3: Created child process 35e2e4
p35e2e4: Created child process 35e2e5
p35e2e2: Read ./testprog 1 2

p35e2e3: Read 0:��t
p35e2e5: Read 0:��t
p35e2e4: Read 0:��t

这是我的代码:

#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

#define BUFFERSIZE 1024

int main(int argc, char** argv) {
        // reads argument
        int maxpc = atoi(argv[1]);

        // creates children
        printf("Main process %x\n", getpid());
        pid_t pid = 0;
        for(int pc = 0; pc < maxpc && pid == 0; pc++) {
                pid = fork();
                if(pid != 0) printf("p%x: Created child process %x\n", getpid(), pid);
        }

        // reads lines and prints
        char command[BUFFERSIZE];
        fgets(command, BUFFERSIZE, stdin);
        printf("p%x: Read %s\n", getpid(), command);

        // closes
        wait(NULL);
        exit(0);
}

这是我的输入文件

batchcmds

./testprog 1 2
./testprog 3 1
./testprog 2 2
./testprog 1 1
./testprog 2 1
./testprog 1 3
./testprog 2 3

我查遍了,没有发现任何类似的问题。我对 UNIX 和 C 都比较陌生(我习惯了 C++),所以我怀疑我错过了一些关于 i/o 的基本知识。任何帮助将不胜感激。

c unix process io
1个回答
0
投票

在您的代码中,您仅从创建子进程的循环之外的标准输入读取一行。这意味着只有一个进程从标准输入中读取数据,其余进程只是退出而不读取任何内容。 您需要确保每个子进程分别从标准输入读取。

#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

#define BUFFERSIZE 1024

int main(int argc, char** argv) {
    // reads argument
    int maxpc = atoi(argv[1]);

    // creates children
    printf("Main process %x\n", getpid());
    pid_t pid = 0;
    for(int pc = 0; pc < maxpc && pid == 0; pc++) {
        pid = fork();
        if(pid != 0) printf("p%x: Created child process %x\n", getpid(), pid);
    }

    // reads lines and prints
    char command[BUFFERSIZE];
    if(pid == 0) { // Child process reads from standard input
        while(fgets(command, BUFFERSIZE, stdin) != NULL) {
            printf("p%x: Read %s", getpid(), command); // print each line
        }
        exit(0); // Child process exits after reading
    }

    // Parent process waits for children to finish
    for(int i = 0; i < maxpc; i++) {
        wait(NULL);
    }
    
    return 0; // Main process exits
}
© www.soinside.com 2019 - 2024. All rights reserved.