Как быть уверенным, что вся строка сразу записывается в файл на С++

Я хочу сделать «межпроцессное взаимодействие» с файлом посередине. производитель записывает сообщения в файл, а потребитель читает его.

Мой вопрос о производителе.

Предположим этот код:

#include <iostream>
#include <fstream>
using namespace std;

int main() {
  // Create and open a "file in the middle" IPC
  ofstream messagefile("filename.txt");

  // Write to the file
  messagefile << "Files can be tricky, hope you are reading all of this string at once\n";

  // Close the file
  MyFile.close();
} 

Есть ли риск того, что сброс буфера (на любом уровне ОС или стандартной библиотеки) очистит эту строку более чем в одной части? Я хочу убедиться, что процессы-потребители считывают все сообщение за один раз. Что ты посоветуешь?

Я знаю, что потребитель может дождаться определенного символа, такого как «\n», но мой вопрос касается производителя.

Заранее большое спасибо

Для этого небольшого текста все должно поместиться в один буфер. Но если у вас есть текст намного большего размера, у вас возникнут проблемы, возможно, с несколькими сбросами. Вы всегда можете использовать блокировку файлов для конкретной ОС, чтобы предотвратить открытие файла другими процессами, пока вы не разблокируете его доступ.

Some programmer dude 17.02.2023 18:42

Это не может быть реализовано надежным способом. Составьте какой-нибудь протокол <70>Files can be tricky, hope you are reading all of this string at once\n.

273K 17.02.2023 18:43

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

Slava 17.02.2023 18:43

Небольшой момент: вам не нужно звонить MyFile.close();. Это сделает деструктор.

Pete Becker 17.02.2023 18:44

Это не указано в стандарте C++. В Linux с локальной файловой системой я ожидаю, что каждый отдельный системный вызов write() будет атомарным.

Sam Varshavchik 17.02.2023 18:44

Да, риск есть, и надежного способа его предотвратить нет.

user253751 17.02.2023 19:02

@SamVarshavchik Я не думаю, что write() гарантированно атомарна в Linux (или любой другой системе с разделением времени). Не в смысле "все это (ничего из этого) идет на диск". Если произойдет сбой системы, вы можете потерять последнюю часть данных. write() предполагается атомарным между процессами и потоками (если два актора пишут «одновременно» в одну и ту же цель, их данные не должны перекрываться) (но см. https://man7.org/linux/man- страницы/man2/write.2.html).

Diego Ferruchelli 17.02.2023 19:16

Вам нужно будет использовать какую-то сигнализацию, чтобы указать, что файл записывается и когда он завершен. Вы действительно не хотите, чтобы задачи записывали в файл одновременно, -- поведение undefined.

Thomas Matthews 17.02.2023 19:19

Я также предлагаю какую-то сигнализацию или событие, чтобы сообщить другому процессу, что в файле есть данные.

Thomas Matthews 17.02.2023 19:20
Запуск PHP на IIS без использования программы установки веб-платформы
Запуск PHP на IIS без использования программы установки веб-платформы
Установщик веб-платформы, предлагаемый компанией Microsoft, перестанет работать 31 декабря 2022 года. Его закрытие привело к тому, что мы не можем...
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Настройка шаблона Metronic с помощью Webpack и Gulp
Настройка шаблона Metronic с помощью Webpack и Gulp
Я пишу эту статью, чтобы поделиться тем, как настроить макет Metronic с помощью Sass, поскольку Metronic предоставляет так много документации, и они...
Уроки CSS 6
Уроки CSS 6
Здравствуйте дорогие читатели, я Ферди Сефа Дюзгюн, сегодня мы продолжим с вами уроки css. Сегодня мы снова продолжим с так называемых классов.
Что такое Css? Для чего он используется?
Что такое Css? Для чего он используется?
CSS, или "Каскадные таблицы стилей", - это язык стилей, используемый в веб-страницах. CSS является одним из основных инструментов веб-разработки...
0
9
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вас беспокоит возможная потеря информации из-за сбоя системы, я бы посоветовал вам использовать ostream::flush плюс какой-то зависящий от операционной системы вызов для действительного сброса буферов ввода-вывода на диск (например, sync() в системах Unix).

Если вас интересует только протокол IPC (то есть вы просто хотите избежать чтения неполных сообщений), использования терминатора должно быть достаточно. В некоторых ситуациях могут быть полезны две разные отдельные «метки» (начало и конец).

Я предполагаю, что у вас одновременно активен только один писатель.

Или, что касается возможной ситуации с потерей данных, просто старайтесь писать чаще и меньшими порциями. :)

Some programmer dude 17.02.2023 18:54

Спасибо за ваш ответ. Я думаю, что, наконец, я должен сделать какой-то протокол. но пока, я надеюсь, я смогу найти надежный способ только со стороны производителя

Behrang 17.02.2023 19:13

Другие вопросы по теме