0

このコードは、Windows (予期しない結果) および Ubuntu で動作するようです。しかし、FreeBSD 9.0 AMD 64 で実行すると、システムがフリーズします。次のようなエラー メッセージが表示されます: ahcich0
: スロット 28 ポート 0 のタイムアウト ありがとう。

#include <cmath>
#include <cstdlib>
#include <sys/time.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
    const string FILENAME = "testfile";
    const string COPYNAME = "copy";
    const int FILES = 5;
    const int SIZE_MULTIPLIER = 6;
    const int BUFFER_SIZE = pow(2.0, 16);

    time_t times[2][FILES];

    srand (time(NULL));

    // create test files
    for (int i = 1; i < FILES + 1; i++){
        ofstream os;
        string filename(FILENAME);
        filename += (char)i + 48;
        os.open(filename.c_str(), ios::binary);
        if (os.is_open()){
            cout << "Writing file " << i << " of " << FILES;
            long filesize =pow(2.0, i * SIZE_MULTIPLIER);
            cout << " (" << filesize << " bytes)" <<  endl;

            while(filesize--){
                os << (char)(rand() % 256);
            }
            cout << os.tellp() << " bytes written.\n";
            os.close();
        }else{
            cerr << "Could not create file " << filename;
            cerr << endl;
        }
    }

    // copy the files
    timeval tv;
    time_t start;
    char buffer[BUFFER_SIZE];
    char ci;
    for (int i = 0; i < FILES; i++){
        ci = (char)i + 49;
        string filename(FILENAME);
        filename += ci;
        string copyname("c");
        copyname += COPYNAME;
        copyname += ci;

        cout << "Copying file " << filename.c_str() << endl;

        cout << "the c way: "; 
        cout.flush();

        start = time(NULL);

        FILE *pFile = fopen(filename.c_str(), "rb");
        FILE *pCopy = fopen(copyname.c_str(), "wb");
        if (!(pFile == NULL || pCopy == NULL)){
            do{
                int bytesRead = fread(
                    buffer, 1, BUFFER_SIZE, pFile);

                fwrite(buffer, 1, bytesRead, pCopy);
            }while(!feof(pFile));
            fclose(pFile);
            fclose(pCopy);

            cout << " Done.\n";
        }else{
            cerr << "Could not open either " << filename;
            cerr << " or " << copyname << endl;
        }

        times[0][i] = time(NULL) - start;
        remove(copyname.c_str());

        copyname = "cpp";
        copyname += COPYNAME;
        copyname += ci;

        cout << "the c++ way: ";
        cout.flush();

        start = time(NULL);

        ifstream in;
        in.open(filename.c_str(), ios::binary);
        in.rdbuf()->pubsetbuf(buffer, BUFFER_SIZE);
        ofstream out;
        out.open(copyname.c_str(), ios::binary);
        char copyBuffer[BUFFER_SIZE];
        out.rdbuf()->pubsetbuf(copyBuffer, BUFFER_SIZE);

        if (in.is_open() && out.is_open()){
            out << in.rdbuf();
            in.close();
            out.close();
            cout << " Done.\n";
        }else{
            cerr << "Could not open either " << filename;
            cerr << " or " << copyname << endl;
        }

        times[1][i] = time(NULL) - start ;
        remove(copyname.c_str());
    }

    cout << "Summary:\n";
    cout << "\tc\tc++\n";
    for (int i = 0; i < FILES; i++){
        ci = (char)i + 49;
        cout << "copy" << ci << "\t" << times[0][i];
        cout << "\t" << times[1][i] << endl;
    }

    return 0;
}
4

2 に答える 2

1

FILESを4に変更した後(それ以外の場合は非常に時間がかかるため)、プログラムはここで問題なく実行されました。

Writing file 1 of 4 (64 bytes)
64 bytes written.
Writing file 2 of 4 (4096 bytes)
4096 bytes written.
Writing file 3 of 4 (262144 bytes)
262144 bytes written.
Writing file 4 of 4 (16777216 bytes)
16777216 bytes written.
Copying file testfile1
the c way:  Done.
the c++ way:  Done.
Copying file testfile2
the c way:  Done.
the c++ way:  Done.
Copying file testfile3
the c way:  Done.
the c++ way:  Done.
Copying file testfile4
the c way:  Done.
the c++ way:  Done.
Summary:
        c       c++
copy1   0       0
copy2   0       0
copy3   0       0
copy4   0       0

(FreeBSD 9.0-RELEASE-p3 amd64、clang ++でコンパイル)

于 2012-12-23T20:17:24.820 に答える
1

9.0 の achi-driver にバグがあった可能性があり、それは重い負荷の下で現れました。または、同じ負荷の下で失敗していたバグのあるコントローラーであった可能性があります。他の OS では失敗していませんでした。

これは FreeBSD 9.2 でもまだ問題がありますか?

プログラムに関しては、 for だけでなく、読み取り/書き込みループでfeof()も forをチェックする必要があります。ferror()さらに、私の意見では、そのような読み取り/書き込みループは過去のものです。最近では、size_toffset_tが同じ幅 (64 ビット プラットフォーム) である場合mmap()、ソース ファイルとfwriteそれを 1 回で宛先に単純化する必要があります。ほら、ママ、ループじゃない!

于 2013-12-31T04:09:19.677 に答える