更新
我的文件中有很长的行,我在每个第 80 个字符后放置一个换行符(我使用了该sed
命令)。现在程序运行良好。我可以给它们计时,结果也很有意义。
不过,我不知道为什么这会引起问题。
太长了;
在我的 C 程序上使用 /usr/bin/time 命令无法按预期工作。 time命令在C程序之前结束,有时没有输出。例如
/usr/bin/time ./cat_8 lorem_ipsum.txt
问题描述
我正在做第 8 章 K&R 的练习 8.1。
练习8-1。使用 read、write、open 和 close 重写第 7 章中的程序 cat,而不是使用标准库的等效项。进行实验以确定两个版本的相对速度。
摘录自:Brian W. Kernighan。 C 编程语言,第二版
您可以看到下面的程序。我遇到的问题是这两个程序。
我尝试对这些程序进行计时来比较它们。文件大小lorem_ipsum.txt是35M。
me@virtualbox:~$ ls -hs lorem_ipsum.txt
35M lorem_ipsum.txt
time
cat 程序运行没有问题,但由于某种原因我无法从命令中获得结果。谷歌无法提供帮助,我也无能为力。
我用 编译了程序,除了当然gcc
之外没有其他选项。-o
我在 Ubuntu 虚拟机上工作。
有谁知道问题可能是什么或者我做错了什么?
第8章(cat_8程序)
#include <fcntl.h>
#include <syscall.h>
#include <stdio.h>
void error(char *fmt, ...);
/* cat: concatenate file */
int main(int argc, char** argv) {
int fd;
void filecopy(int, int);
char *prog = argv[0]; /* program name for errors */
if (argc == 1)
filecopy(0, 1);
else
while (--argc > 0)
if ((fd = open(*++argv, O_RDONLY, 0)) == -1)
error("%s: can't open %s\n", prog, *argv);
else {
filecopy(fd, 1);
close(fd);
}
return 0;
}
/* filecopy: copy file ifp to file ofp */
void filecopy(int fdin, int fdout) {
char buf[BUFSIZ];
int n;
while ((n = read(fdin, buf, BUFSIZ)) > 0)
write(fdout, buf, n);
}
第7章(cat_7程序)
#include <stdio.h>
#include <stdlib.h>
/* cat: concatenate file, version 2 */
int main(int argc, char* argv[]) {
FILE *fp;
void filecopy(FILE *, FILE *);
char *prog = argv[0]; /* program name for errors */
if (argc == 1)
filecopy(stdin, stdout);
else
while (--argc > 0)
if ((fp = fopen(*++argv, "r")) == NULL) {
fprintf(stderr, "%s: can't open %s\n", prog, *argv);
exit(1);
} else {
filecopy(fp, stdout);
fclose(fp);
}
if (ferror(stdout)) {
fprintf(stderr, "%s: error writing stdout\n", prog);
exit(2);
}
return 0;
}
/* filecopy: copy file ifp to file ofp */
void filecopy(FILE *ifp, FILE *ofp) {
int c;
while ((c = getc(ifp)) != EOF)
putc(c, ofp);
}
答案1
有谁知道问题可能是什么或者我做错了什么?
我不认为你的两个解决方案有什么问题。这些根本不可能请求您所描述的行为......而不故意分叉第二个进程(并且您不调用fork()
),或终止time
进程,或破解内核等。
也许你的电脑坏了。
以前我曾遇到过由静默磁盘损坏引起的奇怪行为。我可能会尝试运行debsums
或rpm --verify -a
检查。
它同样可能是显示输出的软件链中的错误。
例如gnome-terminal 3.22 在输入某些二进制序列时存在崩溃错误。 Linux 内核的多个版本都有这个巨大的错误是通过终端仿真器(“pseudo-tty”)向支持读取行的程序(例如 shell)发送超过 4kB 的数据,可能会丢失一些行。一次转储 35MB 的文本是相对地不寻常,您的操作系统中可能存在一些类似的错误。
如果你可以用一个仅仅 100kB 的输入文件来重现这个问题,这是适合您的另一台计算机这几乎肯定不是损坏的与运行它的主机的方式相同。控制台输出非常慢,也只有几兆字节的可用空间。由于某种原因,运行程序的输出time
将与实际秒数不匹配,但这对于这个问题来说应该不重要。剪贴板文本框不接受我的键盘输入(Firefox 53),因此我/dev/clipboard
根据常见问题解答使用右键单击菜单复制数据。
答案2
看起来该程序有效。
你的时间命令工作正常吗?
尝试:
leisner@y50 ~ $ /usr/bin/time sleep 10s
0.00user 0.00system 0:10.00elapsed 0%CPU (0avgtext+0avgdata 1728maxresident)k
0inputs+0outputs (0major+75minor)pagefaults 0swaps
另外,您是否将输出混合到时间结果中 - 尝试如下操作:
time cat myfile.txt >/dev/null
它不应该——但是在虚拟机中运行会导致额外的缓冲层。