2012-07-25 73 views
0

這段代碼似乎可以在Windows(帶有意想不到的結果)和Ubuntu下工作。但是當我在FreeBSD 9.0 AMD 64下運行它時,會導致系統凍結。我得到這樣的錯誤信息:
ahcich0:插槽28端口超時0
有誰知道問題可能是什麼?
謝謝。在FreeBSD下的c/C++下複製大文件凍結系統

#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; 
} 
+2

簡而言之,您的硬件損壞(或操作系統未正確配置以使用它)。這不是一個編程問題。 – 2012-07-25 20:14:20

+0

你看過'dmesg'說的是什麼嗎? 'df -h'怎麼樣?足夠的磁盤空間? – 2012-07-25 20:15:35

+0

是的,如果在Windows/Linux中它可以正常工作(我假設我們正在討論同一臺機器),可能FreeBSD在硬件上工作時遇到問題。 – Unknown 2012-07-25 20:16:27

回答

1

改變文件到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,鏗鏘++編譯)

1

9.0版本中可能存在achi驅動程序中的一個錯誤,該錯誤顯示在重負載下。或者,它可能是一個有問題的控制器,它在相同的負載下失敗 - 而且在其他操作系統下沒有失敗,因爲它們不會對它造成太大的影響。

這仍然是FreeBSD 9.2的問題嗎?

至於你的程序,你應該在你的讀/寫循環中檢查feof(),而不是ferror()。此外,在我看來,這種讀/寫循環是過去的事情。現在,當size_toffset_t具有相同寬度(64位平臺)時,您應該簡單地將mmap()源文件和fwrite它一次性移入目標。看,馬,沒有循環!