I/O を含む C プログラムの /usr/bin/time は結果を生成しません。

I/O を含む C プログラムの /usr/bin/time は結果を生成しません。

修正する

私のファイルには非常に長い行があり、80番目の文字ごとに改行を入れました(このsedコマンドを使用しました)。これでプログラムが正常に実行されます。時間を測定すると、結果は意味があります。

しかし、これがなぜ問題を引き起こすのかわかりません。

長すぎる。

私のCプログラムで/ usr / bin / timeコマンドを使用すると、期待どおりに機能しません。 timeコマンドはCプログラムの前に終了し、時には出力がない場合があります。例えば

/usr/bin/time ./cat_8 lorem_ipsum.txt

問題の説明

私は Chapter 8 K&R の練習 8.1 をしています。

練習8-1。標準ライブラリと同等の機能を使用する代わりに、読み取り、書き込み、開く、および閉じるを使用して、第7章のcatプログラムを再構築してください。両バージョンの相対速度を決定するために実験を行った。

抜粋:Brian W. Kernighan。 Cプログラミング言語、第2版

以下のプログラムをご覧ください。私が経験している問題はこれら2つのプログラムにあります。

私はこれらのプログラムを比較するタイミングを試しました。ファイルサイズlorem_ipsum.txt35Mです。

me@virtualbox:~$ ls -hs lorem_ipsum.txt
35M lorem_ipsum.txt

timecatプログラムは問題なく実行されますが、何らかの理由でコマンドから結果を得ることはできません。 Googleは助けることができず、私ができることは何もありません。

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

問題が何であるか、私が間違っていることを知っている人はいますか?

2つの解決策に問題はありません。意図的に2番目のプロセスをフォークしたり(呼び出していないfork())プロセスを終了しtimeたり、カーネルをハッキングしなくても、これらの動作を要求することはできません。

コンピュータが故障している可能性があります。

以前は、ディスクの破損が原因で奇妙な動作が発生したことがあります。走ったり確認してみるdebsumsこともrpm --verify -aできますね。

出力を表示するソフトウェアチェーンのバグかもしれません。

例えばgnome-terminal 3.22で特定のバイナリシーケンスを入力するとクラッシュエラーが発生する。 Linuxカーネルにはいくつかのバージョンがあります。この巨大なバグは、ターミナルエミュレータ(「pseudo-tty」)を介して行の読み取りをサポートするプログラム(シェルなど)に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

だからではありません。ただし、仮想マシンで実行すると追加のバッファリング層が発生します。

関連情報