gpt4 book ai didi

c - fork一个进程,并使用管道将数据从文件逐行传输到子进程

转载 作者:行者123 更新时间:2023-11-30 16:26:46 33 4
gpt4 key购买 nike

我的项目是fork,然后使用父进程从文件中逐行读取数据,然后将每一行发送到子进程,子进程必须使用execve将该行作为bc的参数发送,并且输出必须返回到父进程。现在,我只是尝试将数据发送给 child 并正确接收,但它不起作用。我必须使用 select 来确定子级是否有输出供父级获取。

我有一个包含 5 行的文件,我使用 while 循环来遍历该文件。对于每一行,我以为我会从 child 那里取回该行,但它只执行一两行并停止。然后由于某种原因我得到了同一行两次。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <errno.h>
#include <wait.h>


int main(int argc, char *argv[])
{
alarm(60);

fd_set rfds;
fd_set r2fds;
struct timeval tv;
int retval;
int retval2;

int i = argc;
int rc;
FILE *fp;
fp = fopen (argv[1],"r");

char *args[3];
int j = 0;
while (j < i)
{
args[j] = argv[j+2];
j++;
}

int stdin_pipe_fds[2], stdout_pipe_fds[2], stderr_pipe_fds[2];

pipe(stdin_pipe_fds);
pipe(stdout_pipe_fds);
pipe(stderr_pipe_fds);

rc = fork();
if (rc == -1)
{
while (rc == -1)
{
rc = fork();
}
}

pid_t child;
pid_t parent;

if (rc == 0)
{
child = getpid();

close(stdin_pipe_fds[1]);
close(stdout_pipe_fds[0]);
close(stdout_pipe_fds[0]);

close(0);
dup(stdin_pipe_fds[0]);//, 0);
close(stdin_pipe_fds[0]);
close(1);
dup(stdout_pipe_fds[1]);//,1);
close(stdout_pipe_fds[1]);
close(2);
dup(stderr_pipe_fds[1]);//,2);
close(stderr_pipe_fds[1]);
}

if (rc > 0)
{
parent = getpid();

close(stdin_pipe_fds[0]);
close(stdout_pipe_fds[1]);
close(stderr_pipe_fds[1]);
}

char str[100];
char buf2[100];
char buf[100];

FD_ZERO(&rfds);
FD_SET(stdout_pipe_fds[0], &rfds);

tv.tv_sec = 1;
tv.tv_usec = 0;



while ((fgets(str,100,fp)) != NULL)
{
if (rc > 0)
{
int wstatus;
int wsta;
int status;
wsta = write(stdin_pipe_fds[1],str,strlen(str));
retval = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);

if (FD_ISSET(stdout_pipe_fds[0], &rfds))
{
wstatus = read(stdout_pipe_fds[0], buf2, 100);
printf("From child: %s\n",buf2);
if (wstatus == -1)
{
printf("read failed\n");
//continue;
}
//wsta = write(stdin_pipe_fds[1],str,strlen(str));
}


}

if (rc == 0)
{
alarm(60);

scanf("%s",buf);
printf("%s", buf);
}
}

fclose(fp);
}

最佳答案

在 child 身上

您关闭了 stdout_pipe_fds[0] 两次,而不是 stderr_pipe_fds[0]。

scanf("%s", buf) 将从字符串中去除换行符;你可能不想要那样。标准输出,如果您从终端启动,将进行行缓冲;也就是说,需要换行才能触发实际写入。由于您潜入并替换了底层 FD,因此它不知道新的缓冲策略可能是合适的。

在父级中:

您将读取和写入视为返回状态;它们返回读取或写入的字节数。如果读取 0 个字节,则 buf 将包含上次读取的值。我不确定 read() 的目的,我认为它只会把事情搞砸。我认为您需要画出文件描述符如何链接的图片。

建议:使用fork时有一个普遍接受的习惯用法:

if ((rc = fork()) == 0) {
/* do child stuff */
} else if (rc != -1) {
/* do parent stuff */
} else {
/* do error stuff */
}

主要是为了避免扭曲人们的大脑。当它交错时,确实很难阅读。 K&R 中的“K”曾经打趣说“...如果你在编写它时尽可能聪明,你将如何调试它?”

收盘价(0); dup();更好地表示为 dup2(fd, 0)。您可以在自己的机器上编译代码这一事实足以确保 dup2 正常运行。

关于c - fork一个进程,并使用管道将数据从文件逐行传输到子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52964279/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com