无法使用C中的管道发送大于64 KB的数据
我试图通过命名管道将usr/share/dict/words文件(大约971KB)从父进程发送到两个子进程。然而,输出是空的,我没有得到任何错误。我等了一分钟,但什么也没有改变。该程序可以很好地处理我尝试使用的10KB数据。我知道管道缓冲区大小是64KB,但有人能解释一下我的方法有什么问题吗: 代码如下: -ptr_child_1表示共享内存指针,映射了1MB的共享段。 -fd和sd是管道,file是文件指针 代码很长,这就是我没有粘贴所有代码的原因。我只是想知道我该如何发送那个大文件 父写入:无法使用C中的管道发送大于64 KB的数据,c,memory,pipe,size,buffer,C,Memory,Pipe,Size,Buffer,我试图通过命名管道将usr/share/dict/words文件(大约971KB)从父进程发送到两个子进程。然而,输出是空的,我没有得到任何错误。我等了一分钟,但什么也没有改变。该程序可以很好地处理我尝试使用的10KB数据。我知道管道缓冲区大小是64KB,但有人能解释一下我的方法有什么问题吗: 代码如下: -ptr_child_1表示共享内存指针,映射了1MB的共享段。 -fd和sd是管道,file是文件指针 代码很长,这就是我没有粘贴所有代码的原因。我只是想知道我该如何发送那个大文件 父写入:
mknod(FIFO_1, S_IFIFO | 0666, 0);
mknod(FIFO_2, S_IFIFO | 0666, 0);
// open pipes
int fd = open(FIFO_1, O_WRONLY);
int sd = open(FIFO_2, O_WRONLY);
char str[3000];
while(fgets(str, sizeof(str), file) > 0)
{
// write all lines of file
write(fd, str, strlen(str));
write(sd, str, strlen(str));
}
// send EOF explicitly
write(fd, "\0", 1);
write(sd, "\0", 1);
// close file and pipes
close(fd);
close(sd);
fclose(file);
儿童阅读:
int num;
char s[3000];
while((num = read(fd, s, sizeof(s))) > 0)
{
sprintf(ptr_child_1, "%s", s);
ptr_child_1 += num;
}
// close pipe
close(fd);
如果看不到所有的文件,很难说。我的第一个建议是从所有这些调用(read、write、mknod、open等)中获取返回值,并在出现问题时开始使用perror()打印错误消息。相对于父项,子项在哪里生成?确保在父级开始写入FIFO之前创建子级。否则,您的父级将写入64K,然后阻塞,直到管道清空。如果在父级尝试写入之前创建子级,则即使父级正在写入管道,子级也可以从管道中读取,因此大小限制不是问题。似乎您在让子级从FIFO中读取之前尝试写入FIFO。在现代系统中,管道和FIFO的缓冲区大小有64KIB的限制——很久以前只有5KIB。我们需要查看过程控制代码。
sprintf(ptr_child_1,“%s”,s)代码>要求s
为字符串。它不是(导致UB),因为它可能缺少空字符。建议sprintf(ptr_child_1,'%s',num,s)代码>相反。如果看不到所有文件,很难判断。我的第一个建议是从所有这些调用(read、write、mknod、open等)中获取返回值,并在出现问题时开始使用perror()打印错误消息。相对于父项,子项在哪里生成?确保在父级开始写入FIFO之前创建子级。否则,您的父级将写入64K,然后阻塞,直到管道清空。如果在父级尝试写入之前创建子级,则即使父级正在写入管道,子级也可以从管道中读取,因此大小限制不是问题。似乎您在让子级从FIFO中读取之前尝试写入FIFO。在现代系统中,管道和FIFO的缓冲区大小有64KIB的限制——很久以前只有5KIB。我们需要查看过程控制代码。sprintf(ptr_child_1,“%s”,s)代码>要求s
为字符串。它不是(导致UB),因为它可能缺少空字符。建议sprintf(ptr_child_1,'%s',num,s)代码>取而代之。