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판

아래 프로그램을 보실 수 있습니다. 제가 겪고 있는 문제는 이 두 프로그램에 있습니다.

나는 이 프로그램들을 비교하기 위해 타이밍을 시험해 보았습니다. 파일 크기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

문제가 무엇인지, 내가 뭘 잘못하고 있는지 아는 사람이 있나요?

두 가지 솔루션에 아무런 문제가 없습니다. 의도적으로 두 번째 프로세스를 포크하거나(호출하지 않는 fork()) 프로세스를 종료 time하거나 커널을 해킹하지 않고는 이러한 동작을 요청하는 것이 불가능합니다.

컴퓨터가 고장났을 수도 있습니다.

이전에 자동 디스크 손상으로 인해 이상한 동작이 발생한 적이 있습니다. 달리 debsums거나 rpm --verify -a확인해 볼 수도 있겠네요.

출력을 표시하는 소프트웨어 체인의 버그일 수도 있습니다.

예를 들어gnome-terminal 3.22에 특정 바이너리 시퀀스를 입력할 때 충돌 오류가 발생함. Linux 커널에는 여러 버전이 있습니다.이 거대한 버그는 터미널 에뮬레이터("pseudo-tty")를 통해 행 읽기를 지원하는 프로그램(예: 쉘)에 4kB 이상의 데이터를 전송하여 일부 행이 손실될 수 있습니다.. 35MB의 텍스트 덤프는비교적일반적으로 운영 체제에 유사한 버그가 있을 수 있습니다.

단지 100kB의 입력 파일로 이 문제를 재현할 수 있다면,여기 당신을 위한 또 다른 컴퓨터가 있습니다이것은 거의 확실하지 않습니다손상된실행 중인 호스트와 동일한 방식입니다. 콘솔 출력은 매우 느리며 사용 가능한 공간은 몇 메가바이트뿐입니다. 어떤 이유로 프로그램 실행 결과는 time실제 시간(초)과 일치하지 않지만 이 질문에서는 문제가 되지 않습니다. 클립보드 텍스트 상자는 키보드 입력(Firefox 53)을 허용하지 않으므로 /dev/clipboardFAQ에 따라 오른쪽 클릭 메뉴를 사용하여 데이터를 복사합니다.

답변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

그래서는 안 됩니다. 하지만 가상 머신에서 실행하면 추가 버퍼링 계층이 발생합니다.

관련 정보