Альтернатива bash sync в C ++ - PullRequest
0 голосов
/ 14 февраля 2019

Я пишу код обработки файлов с использованием C ++.Проблема в том, что после записи в файл происходит немедленное отключение питания, файл не записывается.

Как я обнаружил, проблема связана с задержкой записи из системного буфера в постоянное хранилище файлов.

Я пришел к этому сценарию командой bash sync.Вот фрагмент кода

cout << "Writting to file" << endl;
ofstream fout("demo.dat", ios::out);
fout << "hello world" <<flush;
fout.close();
system("sync");
cout << "file written" << endl << "Sleeping for 3 secs"<<endl;
this_thread::sleep_for(chrono::seconds(3)); //disconnect power here
... some more statements

Проблема в том, что system () считается плохим, учитывая производительность, поскольку мне приходится очень часто записывать файлы.

Пожалуйста, дайте мне знать, если C ++ предоставляет какие-либолучший способ.

Я пытался использовать std :: flush, pubsync (), но он не работает.

Я выполняю обработку файлов в стиле C ++, поэтому не могу использовать обработку файлов в стиле C.

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Если вас беспокоит производительность, то fsync будет быстрее, чем sync, поскольку последний будет передавать все данные, кэшированные ядром и ожидающие записи в контроллер жесткого диска, а не только данные, привязанные к вашему конкретномуфайл.

Вы даже можете быть быстрее, используя следующий системный вызов:

/* _POSIX_SYNCHRONIZED_IO should be defined in <unistd.h> */
int fdatasync(int fd) 

Это похоже на fsync, но без передачи управляющей информации на контроллер (например, время модификации инода,..).

В качестве альтернативы вам может быть интересно открыть файл со следующим флагом O_DSYNC: это эквивалентно выполнению fdatasync() после каждого write()

Помнитечто даже с этими системными вызовами нет никакой гарантии, что данные физически записываются на жесткий диск в случае сбоя питания, а только в том случае, если они были переданы на контроллер жесткого диска.

0 голосов
/ 14 февраля 2019
#include <fstream>
#include <iostream>
#include <unistd.h>

using namespace std;

class sync_filebuf : public filebuf
{
public:
    sync_filebuf(ofstream &fout)
    {
        sync_filebuf *fbuf;
        fbuf = static_cast<sync_filebuf *>(fout.rdbuf());
        fsync(fbuf->_M_file.fd());
    }
};

int main()
{
    cout << "Writting to file" << endl;
    ofstream fout("demo.dat", ios::out);
    fout << "hello world" <<flush;
    fout.flush();
    sync_filebuf x(fout);
    fout.close();
    cout << "file written" << endl << "Sleeping for 3 secs"<<endl;
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...