gpt4 book ai didi

c - 在处理庞大的管道数据时需要建议

转载 作者:太空宇宙 更新时间:2023-11-04 07:47:01 26 4
gpt4 key购买 nike

我正在练习使用管道系统调用的 C 代码,它适用于小块数据。但是当数据超出管道容量时,就会发生死锁。

我的测试系统是 Debian Sid,但我相信它与其他 Linux 发行版有共同点。这段代码在输入文件“/tmp/a.out”足够小以适合管道时运行良好,但由于文件高达 1M 而被阻止。

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

#define CHUNK 2048
int main() {
int fd=open("/tmp/a.out",O_RDONLY);
int pin[2];
int pout[2];

int nread;
char buff[CHUNK];

pipe(pin);
pipe(pout);
int rc;
pid_t pid=fork();
if (pid == 0) {
close(pin[1]);
dup2(pin[0],STDIN_FILENO);
close(pout[0]);
dup2(pout[1],STDOUT_FILENO);

execlp("cat","cat",(char *)0);
} else if (pid > 0) {
close(pin[0]);
close(pout[1]);

/* I think dead lock occurs here, but i can't figure out a way to avoid it */
while ( (nread=read(fd,buff,CHUNK)) > 0) write(pin[1],buff,nread);
close(pin[1]);
while ( (nread=read(pout[0],buff,CHUNK)) >0) write(STDOUT_FILENO,buff,nread);



waitpid(pid,&rc,0);
exit(rc);

} else {
perror("fork");
exit(errno);
}
}

有什么建议吗?我知道 Python 的子进程类有类似 subprocess.communicate() 的东西来避免这种死锁,但我不知道如何在 C 中处理它。

非常感谢。

最佳答案

第一个进程通过管道进入 cat 并且 cat 通过管道返回到第一个进程。因此,要使 cat 不阻塞返回管道,第一个进程还必须排空该管道。例如:

fcntl(pout[0], F_SETFL, fcntl(pout[0], F_GETFL) | O_NONBLOCK);
while((nread=read(fd, buff, CHUNK)) > 0) {
write(pin[1], buff, nread); // TODO: check errors and partial writes here.
while((nread=read(pout[0],buff,CHUNK)) > 0) // pout[0] must be set into non-blocking mode.
write(STDOUT_FILENO, buff, nread);
}

更健壮的方法是将pin[1]pout[0]都设置为非阻塞模式,使用select判断pin[1]是否准备好写入,pout[0]是否准备好读取,然后进行相应的写入/读取,并处理部分读写。

关于c - 在处理庞大的管道数据时需要建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56264746/

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